System.register("chunks:///_virtual/advancingfront.js", ['./cjs-loader.mjs'], function (exports, module) {
  var loader;
  return {
    setters: [function (module) {
      loader = module.default;
    }],
    execute: function () {
      exports('default', void 0);

      var _cjsExports;

      var __cjsMetaURL = exports('__cjsMetaURL', module.meta.url);

      loader.define(__cjsMetaURL, function (exports$1, require, module, __filename, __dirname) {
        /*
         * Note
         * ====
         * the structure of this JavaScript version of poly2tri intentionally follows
         * as closely as possible the structure of the reference C++ version, to make it 
         * easier to keep the 2 versions in sync.
         */
        // -------------------------------------------------------------------------Node

        /**
         * Advancing front node
         * @constructor
         * @private
         * @struct
         * @param {!XY} p - Point
         * @param {Triangle=} t triangle (optional)
         */
        var Node = function Node(p, t) {
          /** @type {XY} */
          this.point = p;
          /** @type {Triangle|null} */

          this.triangle = t || null;
          /** @type {Node|null} */

          this.next = null;
          /** @type {Node|null} */

          this.prev = null;
          /** @type {number} */

          this.value = p.x;
        }; // ---------------------------------------------------------------AdvancingFront

        /**
         * @constructor
         * @private
         * @struct
         * @param {Node} head
         * @param {Node} tail
         */


        var AdvancingFront = function AdvancingFront(head, tail) {
          /** @type {Node} */
          this.head_ = head;
          /** @type {Node} */

          this.tail_ = tail;
          /** @type {Node} */

          this.search_node_ = head;
        };
        /** @return {Node} */


        AdvancingFront.prototype.head = function () {
          return this.head_;
        };
        /** @param {Node} node */


        AdvancingFront.prototype.setHead = function (node) {
          this.head_ = node;
        };
        /** @return {Node} */


        AdvancingFront.prototype.tail = function () {
          return this.tail_;
        };
        /** @param {Node} node */


        AdvancingFront.prototype.setTail = function (node) {
          this.tail_ = node;
        };
        /** @return {Node} */


        AdvancingFront.prototype.search = function () {
          return this.search_node_;
        };
        /** @param {Node} node */


        AdvancingFront.prototype.setSearch = function (node) {
          this.search_node_ = node;
        };
        /** @return {Node} */


        AdvancingFront.prototype.findSearchNode = function ()
        /*x*/
        {
          // TODO: implement BST index
          return this.search_node_;
        };
        /**
         * @param {number} x value
         * @return {Node}
         */


        AdvancingFront.prototype.locateNode = function (x) {
          var node = this.search_node_;
          /* jshint boss:true */

          if (x < node.value) {
            while (node = node.prev) {
              if (x >= node.value) {
                this.search_node_ = node;
                return node;
              }
            }
          } else {
            while (node = node.next) {
              if (x < node.value) {
                this.search_node_ = node.prev;
                return node.prev;
              }
            }
          }

          return null;
        };
        /**
         * @param {!XY} point - Point
         * @return {Node}
         */


        AdvancingFront.prototype.locatePoint = function (point) {
          var px = point.x;
          var node = this.findSearchNode(px);
          var nx = node.point.x;

          if (px === nx) {
            // Here we are comparing point references, not values
            if (point !== node.point) {
              // We might have two nodes with same x value for a short time
              if (point === node.prev.point) {
                node = node.prev;
              } else if (point === node.next.point) {
                node = node.next;
              } else {
                throw new Error('poly2tri Invalid AdvancingFront.locatePoint() call');
              }
            }
          } else if (px < nx) {
            /* jshint boss:true */
            while (node = node.prev) {
              if (point === node.point) {
                break;
              }
            }
          } else {
            while (node = node.next) {
              if (point === node.point) {
                break;
              }
            }
          }

          if (node) {
            this.search_node_ = node;
          }

          return node;
        }; // ----------------------------------------------------------------------Exports


        module.exports = AdvancingFront;
        module.exports.Node = Node; // #endregion ORIGINAL CODE

        _cjsExports = exports('default', module.exports);
        module.exports.Node;
      }, {});
    }
  };
});

System.register("chunks:///_virtual/AnimateRotate.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc'], function (exports) {
  var _inheritsLoose, cclegacy, _decorator, Component;

  return {
    setters: [function (module) {
      _inheritsLoose = module.inheritsLoose;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Component = module.Component;
    }],
    execute: function () {
      var _dec, _class;

      cclegacy._RF.push({}, "161f4/JnUZCRbPMNTlhsUfz", "AnimateRotate", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var AnimateRotate = exports('AnimateRotate', (_dec = ccclass('AnimateRotate'), _dec(_class = /*#__PURE__*/function (_Component) {
        _inheritsLoose(AnimateRotate, _Component);

        function AnimateRotate() {
          return _Component.apply(this, arguments) || this;
        }

        var _proto = AnimateRotate.prototype;

        _proto.start = function start() {};

        _proto.update = function update(deltaTime) {};

        return AnimateRotate;
      }(Component)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/assert.js", ['./cjs-loader.mjs'], function (exports, module) {
  var loader;
  return {
    setters: [function (module) {
      loader = module.default;
    }],
    execute: function () {
      exports('default', void 0);

      var _cjsExports;

      var __cjsMetaURL = exports('__cjsMetaURL', module.meta.url);

      loader.define(__cjsMetaURL, function (exports$1, require, module, __filename, __dirname) {
        /*
         * Function added in the JavaScript version (was not present in the c++ version)
         */

        /**
         * assert and throw an exception.
         *
         * @private
         * @param {boolean} condition   the condition which is asserted
         * @param {string} message      the message which is display is condition is falsy
         */
        function assert(condition, message) {
          if (!condition) {
            throw new Error(message || "Assert Failed");
          }
        }

        module.exports = assert; // #endregion ORIGINAL CODE

        _cjsExports = exports('default', module.exports);
      }, {});
    }
  };
});

System.register("chunks:///_virtual/AudioManager.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './GlobalData.ts', './ResourcesUtils.ts'], function (exports) {
  var _createClass, cclegacy, assert, AudioClip, warn, clamp01, GlobalData, ResourcesUtils;

  return {
    setters: [function (module) {
      _createClass = module.createClass;
    }, function (module) {
      cclegacy = module.cclegacy;
      assert = module.assert;
      AudioClip = module.AudioClip;
      warn = module.warn;
      clamp01 = module.clamp01;
    }, function (module) {
      GlobalData = module.GlobalData;
    }, function (module) {
      ResourcesUtils = module.ResourcesUtils;
    }],
    execute: function () {
      cclegacy._RF.push({}, "67e960kltdOvZytphUapfa0", "AudioManager", undefined); // TODO： 处理魔法数字


      var AudioManager = exports('AudioManager', /*#__PURE__*/function () {
        function AudioManager() {
          // 缓存 后续可以缓存LRU的
          this.soundAudioClipMap = new Map();
          this.soundVolume = 1;
        }

        var _proto = AudioManager.prototype; // init AudioManager in GameRoot.

        _proto.init = function init(audioSource) {
          this.soundVolume = this.getConfiguration(false) ? 1 : 0;
          AudioManager._audioSource = audioSource;
        };

        _proto.getConfiguration = function getConfiguration(isMusic) {
          var state;

          if (isMusic) {
            state = GlobalData.getInstance().getGlobalStorgeData('music');
          } else {
            state = GlobalData.getInstance().getGlobalStorgeData('sound');
          } // console.log('Config for [' + (isMusic ? 'Music' : 'Sound') + '] is ' + state);


          return state === undefined || state === 'true' ? true : false;
        }
        /**
         * 播放音乐
         * @param {String} name 音乐名称可通过constants.AUDIO_MUSIC 获取
         * @param {Boolean} loop 是否循环播放
         */
        ;

        _proto.playMusic = function playMusic(loop) {
          var audioSource = AudioManager._audioSource;
          assert(audioSource, 'AudioManager not inited!');
          audioSource.loop = loop;

          if (!audioSource.playing) {
            audioSource.play();
          }
        }
        /**
         * 播放音效
         * @param {String} name 音效名称可通过constants.AUDIO_SOUND 获取
         */
        ;

        _proto.playSound = function playSound(name) {
          var _this = this;

          var audioSource = AudioManager._audioSource;

          if (!audioSource) {
            console.log(audioSource, 'AudioManager not inited!');
            return;
          } // TODO:需要设置


          var path = "audio/sound/";

          if (this.soundAudioClipMap.has(path)) {
            audioSource.playOneShot(this.soundAudioClipMap.get(path), audioSource.volume ? this.soundVolume / audioSource.volume : 0);
          } else {
            ResourcesUtils.loadRes(ResourcesUtils.BUNDLE_NAME_UI, path + name, AudioClip, function (err, clip) {
              if (err) {
                warn('load audioClip failed: ', err);
                return;
              }

              _this.soundAudioClipMap.set(path, clip); // NOTE: the second parameter is volume scale.


              audioSource.playOneShot(clip, audioSource.volume ? _this.soundVolume / audioSource.volume : 0);
            });
          }
        };

        _proto.setMusicVolume = function setMusicVolume(flag) {
          var audioSource = AudioManager._audioSource;
          assert(audioSource, 'AudioManager not inited!');
          flag = clamp01(flag);
          audioSource.volume = flag;
        };

        _proto.setSoundVolume = function setSoundVolume(flag) {
          this.soundVolume = flag;
        };

        _proto.openMusic = function openMusic() {
          this.setMusicVolume(0.8);
          GlobalData.getInstance().setGlobalStorgeData('music', 'true');
        };

        _proto.closeMusic = function closeMusic() {
          this.setMusicVolume(0);
          GlobalData.getInstance().setGlobalStorgeData('music', 'false');
        };

        _proto.openSound = function openSound() {
          this.setSoundVolume(1);
          GlobalData.getInstance().setGlobalStorgeData('sound', 'true');
        };

        _proto.closeSound = function closeSound() {
          this.setSoundVolume(0);
          GlobalData.getInstance().setGlobalStorgeData('sound', 'false');
        };

        _createClass(AudioManager, null, [{
          key: "instance",
          get: function get() {
            if (this._instance) {
              return this._instance;
            }

            this._instance = new AudioManager();
            return this._instance;
          }
        }]);

        return AudioManager;
      }());
      AudioManager._instance = void 0;
      AudioManager._audioSource = void 0;

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/btnAdapter.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './AudioManager.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Button, Component, AudioManager;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Button = module.Button;
      Component = module.Component;
    }, function (module) {
      AudioManager = module.AudioManager;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _class, _class2, _descriptor, _descriptor2, _descriptor3, _descriptor4;

      cclegacy._RF.push({}, "432703l6gdP866dv3qQvXS5", "btnAdapter", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property,
          menu = _decorator.menu,
          requireComponent = _decorator.requireComponent,
          disallowMultiple = _decorator.disallowMultiple;
      var btnAdapter = exports('btnAdapter', (_dec = ccclass("btnAdapter"), _dec2 = menu('自定义组件/btnAdapter'), _dec3 = requireComponent(Button), _dec4 = property({
        tooltip: '点击后是否播放点击音效'
      }), _dec5 = property({
        tooltip: '点击音效名'
      }), _dec6 = property({
        tooltip: '是否禁止快速二次点击'
      }), _dec7 = property({
        tooltip: '点击后多久才能再次点击,仅isPreventSecondClick为true生效'
      }), _dec(_class = _dec2(_class = _dec3(_class = disallowMultiple(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(btnAdapter, _Component);

        function btnAdapter() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;
          /**
           * 点击后是否播放点击音效
           * @property isPlaySound
           * @type {Boolean}
           * @default true
           */

          _initializerDefineProperty(_this, "isPlaySound", _descriptor, _assertThisInitialized(_this));
          /**
           * 点击音效名
           * @property clickSoundName
           * @type {String}
           * @default true
           */


          _initializerDefineProperty(_this, "clickSoundName", _descriptor2, _assertThisInitialized(_this));
          /**
           * 是否禁止快速二次点击
           * @property isPreventSecondClick
           * @type {Boolean}
           * @default true
           */


          _initializerDefineProperty(_this, "isPreventSecondClick", _descriptor3, _assertThisInitialized(_this));
          /**
           * 点击后多久才能再次点击,仅isPreventSecondClick为true生效
           * @property preventTime
           * @type {number}
           * @default true
           */


          _initializerDefineProperty(_this, "preventTime", _descriptor4, _assertThisInitialized(_this));

          return _this;
        }

        var _proto = btnAdapter.prototype;

        _proto.start = function start() {
          var _this2 = this;

          var button = this.node.getComponent(Button);
          this.node.on('click', function () {
            if (_this2.isPreventSecondClick) {
              button.interactable = false;

              _this2.scheduleOnce(function () {
                if (button.node) button.interactable = true;
              }, _this2.preventTime);
            } //


            if (_this2.isPlaySound) AudioManager.instance.playSound(_this2.clickSoundName);
          });
        } // update (dt) {},
        ;

        return btnAdapter;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "isPlaySound", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return true;
        }
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "clickSoundName", [_dec5], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return 'click';
        }
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "isPreventSecondClick", [_dec6], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return false;
        }
      }), _descriptor4 = _applyDecoratedDescriptor(_class2.prototype, "preventTime", [_dec7], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return 2;
        }
      })), _class2)) || _class) || _class) || _class) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/ChangeCollider2DGroup.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, CCInteger, Collider2D, RigidBody2D, Component;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      CCInteger = module.CCInteger;
      Collider2D = module.Collider2D;
      RigidBody2D = module.RigidBody2D;
      Component = module.Component;
    }],
    execute: function () {
      var _dec, _dec2, _class, _class2, _descriptor;

      cclegacy._RF.push({}, "8e9cfNQ5UNF9Y48m5faH51m", "ChangeCollider2DGroup", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var ChangeCollider2DGroup = exports('ChangeCollider2DGroup', (_dec = ccclass('ChangeCollider2DGroup'), _dec2 = property(CCInteger), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(ChangeCollider2DGroup, _Component);

        function ChangeCollider2DGroup() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "group", _descriptor, _assertThisInitialized(_this));

          return _this;
        }

        var _proto = ChangeCollider2DGroup.prototype;

        _proto.start = function start() {
          var _this2 = this;

          var components = this.node.getComponents(Collider2D);
          components.forEach(function (element) {
            element.group = _this2.group;
          });
          this.node.getComponent(RigidBody2D).group = this.group;
        };

        _proto.update = function update(deltaTime) {};

        return ChangeCollider2DGroup;
      }(Component), _descriptor = _applyDecoratedDescriptor(_class2.prototype, "group", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return 0;
        }
      }), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/clipper.js", ['./cjs-loader.mjs'], function (exports, module) {
  var loader;
  return {
    setters: [function (module) {
      loader = module.default;
    }],
    execute: function () {
      exports('default', void 0);

      var _cjsExports;

      var __cjsMetaURL = exports('__cjsMetaURL', module.meta.url);

      loader.define(__cjsMetaURL, function (exports$1, require, module, __filename, __dirname) {
        var ClipperLib = {};
        var isNode = false;

        if (typeof module !== 'undefined' && module.exports) {
          module.exports = ClipperLib;
          isNode = true;
        } else {
          if (typeof document !== "undefined") window.ClipperLib = ClipperLib;else self['ClipperLib'] = ClipperLib;
        }

        var navigator_appName;

        if (!isNode) {
          var nav = navigator.userAgent.toString().toLowerCase();
          navigator_appName = navigator.appName;
        } else {
          var nav = "chrome"; // Node.js uses Chrome's V8 engine

          navigator_appName = "Netscape"; // Firefox, Chrome and Safari returns "Netscape", so Node.js should also
        } // Browser test to speedup performance critical functions


        var browser = {};
        if (nav.indexOf("chrome") != -1 && nav.indexOf("chromium") == -1) browser.chrome = 1;else browser.chrome = 0;
        if (nav.indexOf("chromium") != -1) browser.chromium = 1;else browser.chromium = 0;
        if (nav.indexOf("safari") != -1 && nav.indexOf("chrome") == -1 && nav.indexOf("chromium") == -1) browser.safari = 1;else browser.safari = 0;
        if (nav.indexOf("firefox") != -1) browser.firefox = 1;else browser.firefox = 0;
        if (nav.indexOf("firefox/17") != -1) browser.firefox17 = 1;else browser.firefox17 = 0;
        if (nav.indexOf("firefox/15") != -1) browser.firefox15 = 1;else browser.firefox15 = 0;
        if (nav.indexOf("firefox/3") != -1) browser.firefox3 = 1;else browser.firefox3 = 0;
        if (nav.indexOf("opera") != -1) browser.opera = 1;else browser.opera = 0;
        if (nav.indexOf("msie 10") != -1) browser.msie10 = 1;else browser.msie10 = 0;
        if (nav.indexOf("msie 9") != -1) browser.msie9 = 1;else browser.msie9 = 0;
        if (nav.indexOf("msie 8") != -1) browser.msie8 = 1;else browser.msie8 = 0;
        if (nav.indexOf("msie 7") != -1) browser.msie7 = 1;else browser.msie7 = 0;
        if (nav.indexOf("msie ") != -1) browser.msie = 1;else browser.msie = 0;
        ClipperLib.biginteger_used = null; // Copyright (c) 2005  Tom Wu
        // All Rights Reserved.
        // See "LICENSE" for details.
        // Basic JavaScript BN library - subset useful for RSA encryption.
        // Bits per digit

        var dbits; // (public) Constructor

        function BigInteger(a, b, c) {
          // This test variable can be removed,
          // but at least for performance tests it is useful piece of knowledge
          // This is the only ClipperLib related variable in BigInteger library
          ClipperLib.biginteger_used = 1;
          if (a != null) if ("number" == typeof a && "undefined" == typeof b) this.fromInt(a); // faster conversion
          else if ("number" == typeof a) this.fromNumber(a, b, c);else if (b == null && "string" != typeof a) this.fromString(a, 256);else this.fromString(a, b);
        } // return new, unset BigInteger


        function nbi() {
          return new BigInteger(null);
        } // am: Compute w_j += (x*this_i), propagate carries,
        // c is initial carry, returns final carry.
        // c < 3*dvalue, x < 2*dvalue, this_i < dvalue
        // We need to select the fastest one that works in this environment.
        // am1: use a single mult and divide to get the high bits,
        // max digit bits should be 26 because
        // max internal value = 2*dvalue^2-2*dvalue (< 2^53)


        function am1(i, x, w, j, c, n) {
          while (--n >= 0) {
            var v = x * this[i++] + w[j] + c;
            c = Math.floor(v / 0x4000000);
            w[j++] = v & 0x3ffffff;
          }

          return c;
        } // am2 avoids a big mult-and-extract completely.
        // Max digit bits should be <= 30 because we do bitwise ops
        // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)


        function am2(i, x, w, j, c, n) {
          var xl = x & 0x7fff,
              xh = x >> 15;

          while (--n >= 0) {
            var l = this[i] & 0x7fff;
            var h = this[i++] >> 15;
            var m = xh * l + h * xl;
            l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff);
            c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30);
            w[j++] = l & 0x3fffffff;
          }

          return c;
        } // Alternately, set max digit bits to 28 since some
        // browsers slow down when dealing with 32-bit numbers.


        function am3(i, x, w, j, c, n) {
          var xl = x & 0x3fff,
              xh = x >> 14;

          while (--n >= 0) {
            var l = this[i] & 0x3fff;
            var h = this[i++] >> 14;
            var m = xh * l + h * xl;
            l = xl * l + ((m & 0x3fff) << 14) + w[j] + c;
            c = (l >> 28) + (m >> 14) + xh * h;
            w[j++] = l & 0xfffffff;
          }

          return c;
        }

        if (navigator_appName == "Microsoft Internet Explorer") {
          BigInteger.prototype.am = am2;
          dbits = 30;
        } else if (navigator_appName != "Netscape") {
          BigInteger.prototype.am = am1;
          dbits = 26;
        } else {
          // Mozilla/Netscape seems to prefer am3
          BigInteger.prototype.am = am3;
          dbits = 28;
        }

        BigInteger.prototype.DB = dbits;
        BigInteger.prototype.DM = (1 << dbits) - 1;
        BigInteger.prototype.DV = 1 << dbits;
        var BI_FP = 52;
        BigInteger.prototype.FV = Math.pow(2, BI_FP);
        BigInteger.prototype.F1 = BI_FP - dbits;
        BigInteger.prototype.F2 = 2 * dbits - BI_FP; // Digit conversions

        var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
        var BI_RC = new Array();
        var rr, vv;
        rr = "0".charCodeAt(0);

        for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;

        rr = "a".charCodeAt(0);

        for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;

        rr = "A".charCodeAt(0);

        for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;

        function int2char(n) {
          return BI_RM.charAt(n);
        }

        function intAt(s, i) {
          var c = BI_RC[s.charCodeAt(i)];
          return c == null ? -1 : c;
        } // (protected) copy this to r


        function bnpCopyTo(r) {
          for (var i = this.t - 1; i >= 0; --i) r[i] = this[i];

          r.t = this.t;
          r.s = this.s;
        } // (protected) set from integer value x, -DV <= x < DV


        function bnpFromInt(x) {
          this.t = 1;
          this.s = x < 0 ? -1 : 0;
          if (x > 0) this[0] = x;else if (x < -1) this[0] = x + this.DV;else this.t = 0;
        } // return bigint initialized to value


        function nbv(i) {
          var r = nbi();
          r.fromInt(i);
          return r;
        } // (protected) set from string and radix


        function bnpFromString(s, b) {
          var k;
          if (b == 16) k = 4;else if (b == 8) k = 3;else if (b == 256) k = 8; // byte array
          else if (b == 2) k = 1;else if (b == 32) k = 5;else if (b == 4) k = 2;else {
              this.fromRadix(s, b);
              return;
            }
          this.t = 0;
          this.s = 0;
          var i = s.length,
              mi = false,
              sh = 0;

          while (--i >= 0) {
            var x = k == 8 ? s[i] & 0xff : intAt(s, i);

            if (x < 0) {
              if (s.charAt(i) == "-") mi = true;
              continue;
            }

            mi = false;
            if (sh == 0) this[this.t++] = x;else if (sh + k > this.DB) {
              this[this.t - 1] |= (x & (1 << this.DB - sh) - 1) << sh;
              this[this.t++] = x >> this.DB - sh;
            } else this[this.t - 1] |= x << sh;
            sh += k;
            if (sh >= this.DB) sh -= this.DB;
          }

          if (k == 8 && (s[0] & 0x80) != 0) {
            this.s = -1;
            if (sh > 0) this[this.t - 1] |= (1 << this.DB - sh) - 1 << sh;
          }

          this.clamp();
          if (mi) BigInteger.ZERO.subTo(this, this);
        } // (protected) clamp off excess high words


        function bnpClamp() {
          var c = this.s & this.DM;

          while (this.t > 0 && this[this.t - 1] == c) --this.t;
        } // (public) return string representation in given radix


        function bnToString(b) {
          if (this.s < 0) return "-" + this.negate().toString(b);
          var k;
          if (b == 16) k = 4;else if (b == 8) k = 3;else if (b == 2) k = 1;else if (b == 32) k = 5;else if (b == 4) k = 2;else return this.toRadix(b);
          var km = (1 << k) - 1,
              d,
              m = false,
              r = "",
              i = this.t;
          var p = this.DB - i * this.DB % k;

          if (i-- > 0) {
            if (p < this.DB && (d = this[i] >> p) > 0) {
              m = true;
              r = int2char(d);
            }

            while (i >= 0) {
              if (p < k) {
                d = (this[i] & (1 << p) - 1) << k - p;
                d |= this[--i] >> (p += this.DB - k);
              } else {
                d = this[i] >> (p -= k) & km;

                if (p <= 0) {
                  p += this.DB;
                  --i;
                }
              }

              if (d > 0) m = true;
              if (m) r += int2char(d);
            }
          }

          return m ? r : "0";
        } // (public) -this


        function bnNegate() {
          var r = nbi();
          BigInteger.ZERO.subTo(this, r);
          return r;
        } // (public) |this|


        function bnAbs() {
          return this.s < 0 ? this.negate() : this;
        } // (public) return + if this > a, - if this < a, 0 if equal


        function bnCompareTo(a) {
          var r = this.s - a.s;
          if (r != 0) return r;
          var i = this.t;
          r = i - a.t;
          if (r != 0) return this.s < 0 ? -r : r;

          while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r;

          return 0;
        } // returns bit length of the integer x


        function nbits(x) {
          var r = 1,
              t;

          if ((t = x >>> 16) != 0) {
            x = t;
            r += 16;
          }

          if ((t = x >> 8) != 0) {
            x = t;
            r += 8;
          }

          if ((t = x >> 4) != 0) {
            x = t;
            r += 4;
          }

          if ((t = x >> 2) != 0) {
            x = t;
            r += 2;
          }

          if ((t = x >> 1) != 0) {
            x = t;
            r += 1;
          }

          return r;
        } // (public) return the number of bits in "this"


        function bnBitLength() {
          if (this.t <= 0) return 0;
          return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ this.s & this.DM);
        } // (protected) r = this << n*DB


        function bnpDLShiftTo(n, r) {
          var i;

          for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i];

          for (i = n - 1; i >= 0; --i) r[i] = 0;

          r.t = this.t + n;
          r.s = this.s;
        } // (protected) r = this >> n*DB


        function bnpDRShiftTo(n, r) {
          for (var i = n; i < this.t; ++i) r[i - n] = this[i];

          r.t = Math.max(this.t - n, 0);
          r.s = this.s;
        } // (protected) r = this << n


        function bnpLShiftTo(n, r) {
          var bs = n % this.DB;
          var cbs = this.DB - bs;
          var bm = (1 << cbs) - 1;
          var ds = Math.floor(n / this.DB),
              c = this.s << bs & this.DM,
              i;

          for (i = this.t - 1; i >= 0; --i) {
            r[i + ds + 1] = this[i] >> cbs | c;
            c = (this[i] & bm) << bs;
          }

          for (i = ds - 1; i >= 0; --i) r[i] = 0;

          r[ds] = c;
          r.t = this.t + ds + 1;
          r.s = this.s;
          r.clamp();
        } // (protected) r = this >> n


        function bnpRShiftTo(n, r) {
          r.s = this.s;
          var ds = Math.floor(n / this.DB);

          if (ds >= this.t) {
            r.t = 0;
            return;
          }

          var bs = n % this.DB;
          var cbs = this.DB - bs;
          var bm = (1 << bs) - 1;
          r[0] = this[ds] >> bs;

          for (var i = ds + 1; i < this.t; ++i) {
            r[i - ds - 1] |= (this[i] & bm) << cbs;
            r[i - ds] = this[i] >> bs;
          }

          if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs;
          r.t = this.t - ds;
          r.clamp();
        } // (protected) r = this - a


        function bnpSubTo(a, r) {
          var i = 0,
              c = 0,
              m = Math.min(a.t, this.t);

          while (i < m) {
            c += this[i] - a[i];
            r[i++] = c & this.DM;
            c >>= this.DB;
          }

          if (a.t < this.t) {
            c -= a.s;

            while (i < this.t) {
              c += this[i];
              r[i++] = c & this.DM;
              c >>= this.DB;
            }

            c += this.s;
          } else {
            c += this.s;

            while (i < a.t) {
              c -= a[i];
              r[i++] = c & this.DM;
              c >>= this.DB;
            }

            c -= a.s;
          }

          r.s = c < 0 ? -1 : 0;
          if (c < -1) r[i++] = this.DV + c;else if (c > 0) r[i++] = c;
          r.t = i;
          r.clamp();
        } // (protected) r = this * a, r != this,a (HAC 14.12)
        // "this" should be the larger one if appropriate.


        function bnpMultiplyTo(a, r) {
          var x = this.abs(),
              y = a.abs();
          var i = x.t;
          r.t = i + y.t;

          while (--i >= 0) r[i] = 0;

          for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t);

          r.s = 0;
          r.clamp();
          if (this.s != a.s) BigInteger.ZERO.subTo(r, r);
        } // (protected) r = this^2, r != this (HAC 14.16)


        function bnpSquareTo(r) {
          var x = this.abs();
          var i = r.t = 2 * x.t;

          while (--i >= 0) r[i] = 0;

          for (i = 0; i < x.t - 1; ++i) {
            var c = x.am(i, x[i], r, 2 * i, 0, 1);

            if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) {
              r[i + x.t] -= x.DV;
              r[i + x.t + 1] = 1;
            }
          }

          if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1);
          r.s = 0;
          r.clamp();
        } // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
        // r != q, this != m.  q or r may be null.


        function bnpDivRemTo(m, q, r) {
          var pm = m.abs();
          if (pm.t <= 0) return;
          var pt = this.abs();

          if (pt.t < pm.t) {
            if (q != null) q.fromInt(0);
            if (r != null) this.copyTo(r);
            return;
          }

          if (r == null) r = nbi();
          var y = nbi(),
              ts = this.s,
              ms = m.s;
          var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus

          if (nsh > 0) {
            pm.lShiftTo(nsh, y);
            pt.lShiftTo(nsh, r);
          } else {
            pm.copyTo(y);
            pt.copyTo(r);
          }

          var ys = y.t;
          var y0 = y[ys - 1];
          if (y0 == 0) return;
          var yt = y0 * (1 << this.F1) + (ys > 1 ? y[ys - 2] >> this.F2 : 0);
          var d1 = this.FV / yt,
              d2 = (1 << this.F1) / yt,
              e = 1 << this.F2;
          var i = r.t,
              j = i - ys,
              t = q == null ? nbi() : q;
          y.dlShiftTo(j, t);

          if (r.compareTo(t) >= 0) {
            r[r.t++] = 1;
            r.subTo(t, r);
          }

          BigInteger.ONE.dlShiftTo(ys, t);
          t.subTo(y, y); // "negative" y so we can replace sub with am later

          while (y.t < ys) y[y.t++] = 0;

          while (--j >= 0) {
            // Estimate quotient digit
            var qd = r[--i] == y0 ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2);

            if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) {
              // Try it out
              y.dlShiftTo(j, t);
              r.subTo(t, r);

              while (r[i] < --qd) r.subTo(t, r);
            }
          }

          if (q != null) {
            r.drShiftTo(ys, q);
            if (ts != ms) BigInteger.ZERO.subTo(q, q);
          }

          r.t = ys;
          r.clamp();
          if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder

          if (ts < 0) BigInteger.ZERO.subTo(r, r);
        } // (public) this mod a


        function bnMod(a) {
          var r = nbi();
          this.abs().divRemTo(a, null, r);
          if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r);
          return r;
        } // Modular reduction using "classic" algorithm


        function Classic(m) {
          this.m = m;
        }

        function cConvert(x) {
          if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);else return x;
        }

        function cRevert(x) {
          return x;
        }

        function cReduce(x) {
          x.divRemTo(this.m, null, x);
        }

        function cMulTo(x, y, r) {
          x.multiplyTo(y, r);
          this.reduce(r);
        }

        function cSqrTo(x, r) {
          x.squareTo(r);
          this.reduce(r);
        }

        Classic.prototype.convert = cConvert;
        Classic.prototype.revert = cRevert;
        Classic.prototype.reduce = cReduce;
        Classic.prototype.mulTo = cMulTo;
        Classic.prototype.sqrTo = cSqrTo; // (protected) return "-1/this % 2^DB"; useful for Mont. reduction
        // justification:
        //         xy == 1 (mod m)
        //         xy =  1+km
        //   xy(2-xy) = (1+km)(1-km)
        // x[y(2-xy)] = 1-k^2m^2
        // x[y(2-xy)] == 1 (mod m^2)
        // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
        // should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
        // JS multiply "overflows" differently from C/C++, so care is needed here.

        function bnpInvDigit() {
          if (this.t < 1) return 0;
          var x = this[0];
          if ((x & 1) == 0) return 0;
          var y = x & 3; // y == 1/x mod 2^2

          y = y * (2 - (x & 0xf) * y) & 0xf; // y == 1/x mod 2^4

          y = y * (2 - (x & 0xff) * y) & 0xff; // y == 1/x mod 2^8

          y = y * (2 - ((x & 0xffff) * y & 0xffff)) & 0xffff; // y == 1/x mod 2^16
          // last step - calculate inverse mod DV directly;
          // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints

          y = y * (2 - x * y % this.DV) % this.DV; // y == 1/x mod 2^dbits
          // we really want the negative inverse, and -DV < y < DV

          return y > 0 ? this.DV - y : -y;
        } // Montgomery reduction


        function Montgomery(m) {
          this.m = m;
          this.mp = m.invDigit();
          this.mpl = this.mp & 0x7fff;
          this.mph = this.mp >> 15;
          this.um = (1 << m.DB - 15) - 1;
          this.mt2 = 2 * m.t;
        } // xR mod m


        function montConvert(x) {
          var r = nbi();
          x.abs().dlShiftTo(this.m.t, r);
          r.divRemTo(this.m, null, r);
          if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r);
          return r;
        } // x/R mod m


        function montRevert(x) {
          var r = nbi();
          x.copyTo(r);
          this.reduce(r);
          return r;
        } // x = x/R mod m (HAC 14.32)


        function montReduce(x) {
          while (x.t <= this.mt2) // pad x so am has enough room later
          x[x.t++] = 0;

          for (var i = 0; i < this.m.t; ++i) {
            // faster way of calculating u0 = x[i]*mp mod DV
            var j = x[i] & 0x7fff;
            var u0 = j * this.mpl + ((j * this.mph + (x[i] >> 15) * this.mpl & this.um) << 15) & x.DM; // use am to combine the multiply-shift-add into one call

            j = i + this.m.t;
            x[j] += this.m.am(0, u0, x, i, 0, this.m.t); // propagate carry

            while (x[j] >= x.DV) {
              x[j] -= x.DV;
              x[++j]++;
            }
          }

          x.clamp();
          x.drShiftTo(this.m.t, x);
          if (x.compareTo(this.m) >= 0) x.subTo(this.m, x);
        } // r = "x^2/R mod m"; x != r


        function montSqrTo(x, r) {
          x.squareTo(r);
          this.reduce(r);
        } // r = "xy/R mod m"; x,y != r


        function montMulTo(x, y, r) {
          x.multiplyTo(y, r);
          this.reduce(r);
        }

        Montgomery.prototype.convert = montConvert;
        Montgomery.prototype.revert = montRevert;
        Montgomery.prototype.reduce = montReduce;
        Montgomery.prototype.mulTo = montMulTo;
        Montgomery.prototype.sqrTo = montSqrTo; // (protected) true iff this is even

        function bnpIsEven() {
          return (this.t > 0 ? this[0] & 1 : this.s) == 0;
        } // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)


        function bnpExp(e, z) {
          if (e > 0xffffffff || e < 1) return BigInteger.ONE;
          var r = nbi(),
              r2 = nbi(),
              g = z.convert(this),
              i = nbits(e) - 1;
          g.copyTo(r);

          while (--i >= 0) {
            z.sqrTo(r, r2);
            if ((e & 1 << i) > 0) z.mulTo(r2, g, r);else {
              var t = r;
              r = r2;
              r2 = t;
            }
          }

          return z.revert(r);
        } // (public) this^e % m, 0 <= e < 2^32


        function bnModPowInt(e, m) {
          var z;
          if (e < 256 || m.isEven()) z = new Classic(m);else z = new Montgomery(m);
          return this.exp(e, z);
        } // protected


        BigInteger.prototype.copyTo = bnpCopyTo;
        BigInteger.prototype.fromInt = bnpFromInt;
        BigInteger.prototype.fromString = bnpFromString;
        BigInteger.prototype.clamp = bnpClamp;
        BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
        BigInteger.prototype.drShiftTo = bnpDRShiftTo;
        BigInteger.prototype.lShiftTo = bnpLShiftTo;
        BigInteger.prototype.rShiftTo = bnpRShiftTo;
        BigInteger.prototype.subTo = bnpSubTo;
        BigInteger.prototype.multiplyTo = bnpMultiplyTo;
        BigInteger.prototype.squareTo = bnpSquareTo;
        BigInteger.prototype.divRemTo = bnpDivRemTo;
        BigInteger.prototype.invDigit = bnpInvDigit;
        BigInteger.prototype.isEven = bnpIsEven;
        BigInteger.prototype.exp = bnpExp; // public

        BigInteger.prototype.toString = bnToString;
        BigInteger.prototype.negate = bnNegate;
        BigInteger.prototype.abs = bnAbs;
        BigInteger.prototype.compareTo = bnCompareTo;
        BigInteger.prototype.bitLength = bnBitLength;
        BigInteger.prototype.mod = bnMod;
        BigInteger.prototype.modPowInt = bnModPowInt; // "constants"

        BigInteger.ZERO = nbv(0);
        BigInteger.ONE = nbv(1); // Copyright (c) 2005-2009  Tom Wu
        // All Rights Reserved.
        // See "LICENSE" for details.
        // Extended JavaScript BN functions, required for RSA private ops.
        // Version 1.1: new BigInteger("0", 10) returns "proper" zero
        // Version 1.2: square() API, isProbablePrime fix
        // (public)

        function bnClone() {
          var r = nbi();
          this.copyTo(r);
          return r;
        } // (public) return value as integer


        function bnIntValue() {
          if (this.s < 0) {
            if (this.t == 1) return this[0] - this.DV;else if (this.t == 0) return -1;
          } else if (this.t == 1) return this[0];else if (this.t == 0) return 0; // assumes 16 < DB < 32


          return (this[1] & (1 << 32 - this.DB) - 1) << this.DB | this[0];
        } // (public) return value as byte


        function bnByteValue() {
          return this.t == 0 ? this.s : this[0] << 24 >> 24;
        } // (public) return value as short (assumes DB>=16)


        function bnShortValue() {
          return this.t == 0 ? this.s : this[0] << 16 >> 16;
        } // (protected) return x s.t. r^x < DV


        function bnpChunkSize(r) {
          return Math.floor(Math.LN2 * this.DB / Math.log(r));
        } // (public) 0 if this == 0, 1 if this > 0


        function bnSigNum() {
          if (this.s < 0) return -1;else if (this.t <= 0 || this.t == 1 && this[0] <= 0) return 0;else return 1;
        } // (protected) convert to radix string


        function bnpToRadix(b) {
          if (b == null) b = 10;
          if (this.signum() == 0 || b < 2 || b > 36) return "0";
          var cs = this.chunkSize(b);
          var a = Math.pow(b, cs);
          var d = nbv(a),
              y = nbi(),
              z = nbi(),
              r = "";
          this.divRemTo(d, y, z);

          while (y.signum() > 0) {
            r = (a + z.intValue()).toString(b).substr(1) + r;
            y.divRemTo(d, y, z);
          }

          return z.intValue().toString(b) + r;
        } // (protected) convert from radix string


        function bnpFromRadix(s, b) {
          this.fromInt(0);
          if (b == null) b = 10;
          var cs = this.chunkSize(b);
          var d = Math.pow(b, cs),
              mi = false,
              j = 0,
              w = 0;

          for (var i = 0; i < s.length; ++i) {
            var x = intAt(s, i);

            if (x < 0) {
              if (s.charAt(i) == "-" && this.signum() == 0) mi = true;
              continue;
            }

            w = b * w + x;

            if (++j >= cs) {
              this.dMultiply(d);
              this.dAddOffset(w, 0);
              j = 0;
              w = 0;
            }
          }

          if (j > 0) {
            this.dMultiply(Math.pow(b, j));
            this.dAddOffset(w, 0);
          }

          if (mi) BigInteger.ZERO.subTo(this, this);
        } // (protected) alternate constructor


        function bnpFromNumber(a, b, c) {
          if ("number" == typeof b) {
            // new BigInteger(int,int,RNG)
            if (a < 2) this.fromInt(1);else {
              this.fromNumber(a, c);
              if (!this.testBit(a - 1)) // force MSB set
                this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this);
              if (this.isEven()) this.dAddOffset(1, 0); // force odd

              while (!this.isProbablePrime(b)) {
                this.dAddOffset(2, 0);
                if (this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a - 1), this);
              }
            }
          } else {
            // new BigInteger(int,RNG)
            var x = new Array(),
                t = a & 7;
            x.length = (a >> 3) + 1;
            b.nextBytes(x);
            if (t > 0) x[0] &= (1 << t) - 1;else x[0] = 0;
            this.fromString(x, 256);
          }
        } // (public) convert to bigendian byte array


        function bnToByteArray() {
          var i = this.t,
              r = new Array();
          r[0] = this.s;
          var p = this.DB - i * this.DB % 8,
              d,
              k = 0;

          if (i-- > 0) {
            if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) r[k++] = d | this.s << this.DB - p;

            while (i >= 0) {
              if (p < 8) {
                d = (this[i] & (1 << p) - 1) << 8 - p;
                d |= this[--i] >> (p += this.DB - 8);
              } else {
                d = this[i] >> (p -= 8) & 0xff;

                if (p <= 0) {
                  p += this.DB;
                  --i;
                }
              }

              if ((d & 0x80) != 0) d |= -256;
              if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k;
              if (k > 0 || d != this.s) r[k++] = d;
            }
          }

          return r;
        }

        function bnEquals(a) {
          return this.compareTo(a) == 0;
        }

        function bnMin(a) {
          return this.compareTo(a) < 0 ? this : a;
        }

        function bnMax(a) {
          return this.compareTo(a) > 0 ? this : a;
        } // (protected) r = this op a (bitwise)


        function bnpBitwiseTo(a, op, r) {
          var i,
              f,
              m = Math.min(a.t, this.t);

          for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]);

          if (a.t < this.t) {
            f = a.s & this.DM;

            for (i = m; i < this.t; ++i) r[i] = op(this[i], f);

            r.t = this.t;
          } else {
            f = this.s & this.DM;

            for (i = m; i < a.t; ++i) r[i] = op(f, a[i]);

            r.t = a.t;
          }

          r.s = op(this.s, a.s);
          r.clamp();
        } // (public) this & a


        function op_and(x, y) {
          return x & y;
        }

        function bnAnd(a) {
          var r = nbi();
          this.bitwiseTo(a, op_and, r);
          return r;
        } // (public) this | a


        function op_or(x, y) {
          return x | y;
        }

        function bnOr(a) {
          var r = nbi();
          this.bitwiseTo(a, op_or, r);
          return r;
        } // (public) this ^ a


        function op_xor(x, y) {
          return x ^ y;
        }

        function bnXor(a) {
          var r = nbi();
          this.bitwiseTo(a, op_xor, r);
          return r;
        } // (public) this & ~a


        function op_andnot(x, y) {
          return x & ~y;
        }

        function bnAndNot(a) {
          var r = nbi();
          this.bitwiseTo(a, op_andnot, r);
          return r;
        } // (public) ~this


        function bnNot() {
          var r = nbi();

          for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i];

          r.t = this.t;
          r.s = ~this.s;
          return r;
        } // (public) this << n


        function bnShiftLeft(n) {
          var r = nbi();
          if (n < 0) this.rShiftTo(-n, r);else this.lShiftTo(n, r);
          return r;
        } // (public) this >> n


        function bnShiftRight(n) {
          var r = nbi();
          if (n < 0) this.lShiftTo(-n, r);else this.rShiftTo(n, r);
          return r;
        } // return index of lowest 1-bit in x, x < 2^31


        function lbit(x) {
          if (x == 0) return -1;
          var r = 0;

          if ((x & 0xffff) == 0) {
            x >>= 16;
            r += 16;
          }

          if ((x & 0xff) == 0) {
            x >>= 8;
            r += 8;
          }

          if ((x & 0xf) == 0) {
            x >>= 4;
            r += 4;
          }

          if ((x & 3) == 0) {
            x >>= 2;
            r += 2;
          }

          if ((x & 1) == 0) ++r;
          return r;
        } // (public) returns index of lowest 1-bit (or -1 if none)


        function bnGetLowestSetBit() {
          for (var i = 0; i < this.t; ++i) if (this[i] != 0) return i * this.DB + lbit(this[i]);

          if (this.s < 0) return this.t * this.DB;
          return -1;
        } // return number of 1 bits in x


        function cbit(x) {
          var r = 0;

          while (x != 0) {
            x &= x - 1;
            ++r;
          }

          return r;
        } // (public) return number of set bits


        function bnBitCount() {
          var r = 0,
              x = this.s & this.DM;

          for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x);

          return r;
        } // (public) true iff nth bit is set


        function bnTestBit(n) {
          var j = Math.floor(n / this.DB);
          if (j >= this.t) return this.s != 0;
          return (this[j] & 1 << n % this.DB) != 0;
        } // (protected) this op (1<<n)


        function bnpChangeBit(n, op) {
          var r = BigInteger.ONE.shiftLeft(n);
          this.bitwiseTo(r, op, r);
          return r;
        } // (public) this | (1<<n)


        function bnSetBit(n) {
          return this.changeBit(n, op_or);
        } // (public) this & ~(1<<n)


        function bnClearBit(n) {
          return this.changeBit(n, op_andnot);
        } // (public) this ^ (1<<n)


        function bnFlipBit(n) {
          return this.changeBit(n, op_xor);
        } // (protected) r = this + a


        function bnpAddTo(a, r) {
          var i = 0,
              c = 0,
              m = Math.min(a.t, this.t);

          while (i < m) {
            c += this[i] + a[i];
            r[i++] = c & this.DM;
            c >>= this.DB;
          }

          if (a.t < this.t) {
            c += a.s;

            while (i < this.t) {
              c += this[i];
              r[i++] = c & this.DM;
              c >>= this.DB;
            }

            c += this.s;
          } else {
            c += this.s;

            while (i < a.t) {
              c += a[i];
              r[i++] = c & this.DM;
              c >>= this.DB;
            }

            c += a.s;
          }

          r.s = c < 0 ? -1 : 0;
          if (c > 0) r[i++] = c;else if (c < -1) r[i++] = this.DV + c;
          r.t = i;
          r.clamp();
        } // (public) this + a


        function bnAdd(a) {
          var r = nbi();
          this.addTo(a, r);
          return r;
        } // (public) this - a


        function bnSubtract(a) {
          var r = nbi();
          this.subTo(a, r);
          return r;
        } // (public) this * a


        function bnMultiply(a) {
          var r = nbi();
          this.multiplyTo(a, r);
          return r;
        } // (public) this^2


        function bnSquare() {
          var r = nbi();
          this.squareTo(r);
          return r;
        } // (public) this / a


        function bnDivide(a) {
          var r = nbi();
          this.divRemTo(a, r, null);
          return r;
        } // (public) this % a


        function bnRemainder(a) {
          var r = nbi();
          this.divRemTo(a, null, r);
          return r;
        } // (public) [this/a,this%a]


        function bnDivideAndRemainder(a) {
          var q = nbi(),
              r = nbi();
          this.divRemTo(a, q, r);
          return new Array(q, r);
        } // (protected) this *= n, this >= 0, 1 < n < DV


        function bnpDMultiply(n) {
          this[this.t] = this.am(0, n - 1, this, 0, 0, this.t);
          ++this.t;
          this.clamp();
        } // (protected) this += n << w words, this >= 0


        function bnpDAddOffset(n, w) {
          if (n == 0) return;

          while (this.t <= w) this[this.t++] = 0;

          this[w] += n;

          while (this[w] >= this.DV) {
            this[w] -= this.DV;
            if (++w >= this.t) this[this.t++] = 0;
            ++this[w];
          }
        } // A "null" reducer


        function NullExp() {}

        function nNop(x) {
          return x;
        }

        function nMulTo(x, y, r) {
          x.multiplyTo(y, r);
        }

        function nSqrTo(x, r) {
          x.squareTo(r);
        }

        NullExp.prototype.convert = nNop;
        NullExp.prototype.revert = nNop;
        NullExp.prototype.mulTo = nMulTo;
        NullExp.prototype.sqrTo = nSqrTo; // (public) this^e

        function bnPow(e) {
          return this.exp(e, new NullExp());
        } // (protected) r = lower n words of "this * a", a.t <= n
        // "this" should be the larger one if appropriate.


        function bnpMultiplyLowerTo(a, n, r) {
          var i = Math.min(this.t + a.t, n);
          r.s = 0; // assumes a,this >= 0

          r.t = i;

          while (i > 0) r[--i] = 0;

          var j;

          for (j = r.t - this.t; i < j; ++i) r[i + this.t] = this.am(0, a[i], r, i, 0, this.t);

          for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i);

          r.clamp();
        } // (protected) r = "this * a" without lower n words, n > 0
        // "this" should be the larger one if appropriate.


        function bnpMultiplyUpperTo(a, n, r) {
          --n;
          var i = r.t = this.t + a.t - n;
          r.s = 0; // assumes a,this >= 0

          while (--i >= 0) r[i] = 0;

          for (i = Math.max(n - this.t, 0); i < a.t; ++i) r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n);

          r.clamp();
          r.drShiftTo(1, r);
        } // Barrett modular reduction


        function Barrett(m) {
          // setup Barrett
          this.r2 = nbi();
          this.q3 = nbi();
          BigInteger.ONE.dlShiftTo(2 * m.t, this.r2);
          this.mu = this.r2.divide(m);
          this.m = m;
        }

        function barrettConvert(x) {
          if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m);else if (x.compareTo(this.m) < 0) return x;else {
            var r = nbi();
            x.copyTo(r);
            this.reduce(r);
            return r;
          }
        }

        function barrettRevert(x) {
          return x;
        } // x = x mod m (HAC 14.42)


        function barrettReduce(x) {
          x.drShiftTo(this.m.t - 1, this.r2);

          if (x.t > this.m.t + 1) {
            x.t = this.m.t + 1;
            x.clamp();
          }

          this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3);
          this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2);

          while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1);

          x.subTo(this.r2, x);

          while (x.compareTo(this.m) >= 0) x.subTo(this.m, x);
        } // r = x^2 mod m; x != r


        function barrettSqrTo(x, r) {
          x.squareTo(r);
          this.reduce(r);
        } // r = x*y mod m; x,y != r


        function barrettMulTo(x, y, r) {
          x.multiplyTo(y, r);
          this.reduce(r);
        }

        Barrett.prototype.convert = barrettConvert;
        Barrett.prototype.revert = barrettRevert;
        Barrett.prototype.reduce = barrettReduce;
        Barrett.prototype.mulTo = barrettMulTo;
        Barrett.prototype.sqrTo = barrettSqrTo; // (public) this^e % m (HAC 14.85)

        function bnModPow(e, m) {
          var i = e.bitLength(),
              k,
              r = nbv(1),
              z;
          if (i <= 0) return r;else if (i < 18) k = 1;else if (i < 48) k = 3;else if (i < 144) k = 4;else if (i < 768) k = 5;else k = 6;
          if (i < 8) z = new Classic(m);else if (m.isEven()) z = new Barrett(m);else z = new Montgomery(m); // precomputation

          var g = new Array(),
              n = 3,
              k1 = k - 1,
              km = (1 << k) - 1;
          g[1] = z.convert(this);

          if (k > 1) {
            var g2 = nbi();
            z.sqrTo(g[1], g2);

            while (n <= km) {
              g[n] = nbi();
              z.mulTo(g2, g[n - 2], g[n]);
              n += 2;
            }
          }

          var j = e.t - 1,
              w,
              is1 = true,
              r2 = nbi(),
              t;
          i = nbits(e[j]) - 1;

          while (j >= 0) {
            if (i >= k1) w = e[j] >> i - k1 & km;else {
              w = (e[j] & (1 << i + 1) - 1) << k1 - i;
              if (j > 0) w |= e[j - 1] >> this.DB + i - k1;
            }
            n = k;

            while ((w & 1) == 0) {
              w >>= 1;
              --n;
            }

            if ((i -= n) < 0) {
              i += this.DB;
              --j;
            }

            if (is1) {
              // ret == 1, don't bother squaring or multiplying it
              g[w].copyTo(r);
              is1 = false;
            } else {
              while (n > 1) {
                z.sqrTo(r, r2);
                z.sqrTo(r2, r);
                n -= 2;
              }

              if (n > 0) z.sqrTo(r, r2);else {
                t = r;
                r = r2;
                r2 = t;
              }
              z.mulTo(r2, g[w], r);
            }

            while (j >= 0 && (e[j] & 1 << i) == 0) {
              z.sqrTo(r, r2);
              t = r;
              r = r2;
              r2 = t;

              if (--i < 0) {
                i = this.DB - 1;
                --j;
              }
            }
          }

          return z.revert(r);
        } // (public) gcd(this,a) (HAC 14.54)


        function bnGCD(a) {
          var x = this.s < 0 ? this.negate() : this.clone();
          var y = a.s < 0 ? a.negate() : a.clone();

          if (x.compareTo(y) < 0) {
            var t = x;
            x = y;
            y = t;
          }

          var i = x.getLowestSetBit(),
              g = y.getLowestSetBit();
          if (g < 0) return x;
          if (i < g) g = i;

          if (g > 0) {
            x.rShiftTo(g, x);
            y.rShiftTo(g, y);
          }

          while (x.signum() > 0) {
            if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x);
            if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y);

            if (x.compareTo(y) >= 0) {
              x.subTo(y, x);
              x.rShiftTo(1, x);
            } else {
              y.subTo(x, y);
              y.rShiftTo(1, y);
            }
          }

          if (g > 0) y.lShiftTo(g, y);
          return y;
        } // (protected) this % n, n < 2^26


        function bnpModInt(n) {
          if (n <= 0) return 0;
          var d = this.DV % n,
              r = this.s < 0 ? n - 1 : 0;
          if (this.t > 0) if (d == 0) r = this[0] % n;else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n;
          return r;
        } // (public) 1/this % m (HAC 14.61)


        function bnModInverse(m) {
          var ac = m.isEven();
          if (this.isEven() && ac || m.signum() == 0) return BigInteger.ZERO;
          var u = m.clone(),
              v = this.clone();
          var a = nbv(1),
              b = nbv(0),
              c = nbv(0),
              d = nbv(1);

          while (u.signum() != 0) {
            while (u.isEven()) {
              u.rShiftTo(1, u);

              if (ac) {
                if (!a.isEven() || !b.isEven()) {
                  a.addTo(this, a);
                  b.subTo(m, b);
                }

                a.rShiftTo(1, a);
              } else if (!b.isEven()) b.subTo(m, b);

              b.rShiftTo(1, b);
            }

            while (v.isEven()) {
              v.rShiftTo(1, v);

              if (ac) {
                if (!c.isEven() || !d.isEven()) {
                  c.addTo(this, c);
                  d.subTo(m, d);
                }

                c.rShiftTo(1, c);
              } else if (!d.isEven()) d.subTo(m, d);

              d.rShiftTo(1, d);
            }

            if (u.compareTo(v) >= 0) {
              u.subTo(v, u);
              if (ac) a.subTo(c, a);
              b.subTo(d, b);
            } else {
              v.subTo(u, v);
              if (ac) c.subTo(a, c);
              d.subTo(b, d);
            }
          }

          if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
          if (d.compareTo(m) >= 0) return d.subtract(m);
          if (d.signum() < 0) d.addTo(m, d);else return d;
          if (d.signum() < 0) return d.add(m);else return d;
        }

        var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997];
        var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; // (public) test primality with certainty >= 1-.5^t

        function bnIsProbablePrime(t) {
          var i,
              x = this.abs();

          if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) {
            for (i = 0; i < lowprimes.length; ++i) if (x[0] == lowprimes[i]) return true;

            return false;
          }

          if (x.isEven()) return false;
          i = 1;

          while (i < lowprimes.length) {
            var m = lowprimes[i],
                j = i + 1;

            while (j < lowprimes.length && m < lplim) m *= lowprimes[j++];

            m = x.modInt(m);

            while (i < j) if (m % lowprimes[i++] == 0) return false;
          }

          return x.millerRabin(t);
        } // (protected) true if probably prime (HAC 4.24, Miller-Rabin)


        function bnpMillerRabin(t) {
          var n1 = this.subtract(BigInteger.ONE);
          var k = n1.getLowestSetBit();
          if (k <= 0) return false;
          var r = n1.shiftRight(k);
          t = t + 1 >> 1;
          if (t > lowprimes.length) t = lowprimes.length;
          var a = nbi();

          for (var i = 0; i < t; ++i) {
            //Pick bases at random, instead of starting at 2
            a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]);
            var y = a.modPow(r, this);

            if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
              var j = 1;

              while (j++ < k && y.compareTo(n1) != 0) {
                y = y.modPowInt(2, this);
                if (y.compareTo(BigInteger.ONE) == 0) return false;
              }

              if (y.compareTo(n1) != 0) return false;
            }
          }

          return true;
        } // protected


        BigInteger.prototype.chunkSize = bnpChunkSize;
        BigInteger.prototype.toRadix = bnpToRadix;
        BigInteger.prototype.fromRadix = bnpFromRadix;
        BigInteger.prototype.fromNumber = bnpFromNumber;
        BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
        BigInteger.prototype.changeBit = bnpChangeBit;
        BigInteger.prototype.addTo = bnpAddTo;
        BigInteger.prototype.dMultiply = bnpDMultiply;
        BigInteger.prototype.dAddOffset = bnpDAddOffset;
        BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
        BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
        BigInteger.prototype.modInt = bnpModInt;
        BigInteger.prototype.millerRabin = bnpMillerRabin; // public

        BigInteger.prototype.clone = bnClone;
        BigInteger.prototype.intValue = bnIntValue;
        BigInteger.prototype.byteValue = bnByteValue;
        BigInteger.prototype.shortValue = bnShortValue;
        BigInteger.prototype.signum = bnSigNum;
        BigInteger.prototype.toByteArray = bnToByteArray;
        BigInteger.prototype.equals = bnEquals;
        BigInteger.prototype.min = bnMin;
        BigInteger.prototype.max = bnMax;
        BigInteger.prototype.and = bnAnd;
        BigInteger.prototype.or = bnOr;
        BigInteger.prototype.xor = bnXor;
        BigInteger.prototype.andNot = bnAndNot;
        BigInteger.prototype.not = bnNot;
        BigInteger.prototype.shiftLeft = bnShiftLeft;
        BigInteger.prototype.shiftRight = bnShiftRight;
        BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
        BigInteger.prototype.bitCount = bnBitCount;
        BigInteger.prototype.testBit = bnTestBit;
        BigInteger.prototype.setBit = bnSetBit;
        BigInteger.prototype.clearBit = bnClearBit;
        BigInteger.prototype.flipBit = bnFlipBit;
        BigInteger.prototype.add = bnAdd;
        BigInteger.prototype.subtract = bnSubtract;
        BigInteger.prototype.multiply = bnMultiply;
        BigInteger.prototype.divide = bnDivide;
        BigInteger.prototype.remainder = bnRemainder;
        BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
        BigInteger.prototype.modPow = bnModPow;
        BigInteger.prototype.modInverse = bnModInverse;
        BigInteger.prototype.pow = bnPow;
        BigInteger.prototype.gcd = bnGCD;
        BigInteger.prototype.isProbablePrime = bnIsProbablePrime; // JSBN-specific extension

        BigInteger.prototype.square = bnSquare;
        var Int128 = BigInteger; // BigInteger interfaces not implemented in jsbn:
        // BigInteger(int signum, byte[] magnitude)
        // double doubleValue()
        // float floatValue()
        // int hashCode()
        // long longValue()
        // static BigInteger valueOf(long val)
        // Helper functions to make BigInteger functions callable with two parameters
        // as in original C# Clipper

        Int128.prototype.IsNegative = function () {
          if (this.compareTo(Int128.ZERO) == -1) return true;else return false;
        };

        Int128.op_Equality = function (val1, val2) {
          if (val1.compareTo(val2) == 0) return true;else return false;
        };

        Int128.op_Inequality = function (val1, val2) {
          if (val1.compareTo(val2) != 0) return true;else return false;
        };

        Int128.op_GreaterThan = function (val1, val2) {
          if (val1.compareTo(val2) > 0) return true;else return false;
        };

        Int128.op_LessThan = function (val1, val2) {
          if (val1.compareTo(val2) < 0) return true;else return false;
        };

        Int128.op_Addition = function (lhs, rhs) {
          return new Int128(lhs).add(new Int128(rhs));
        };

        Int128.op_Subtraction = function (lhs, rhs) {
          return new Int128(lhs).subtract(new Int128(rhs));
        };

        Int128.Int128Mul = function (lhs, rhs) {
          return new Int128(lhs).multiply(new Int128(rhs));
        };

        Int128.op_Division = function (lhs, rhs) {
          return lhs.divide(rhs);
        };

        Int128.prototype.ToDouble = function () {
          return parseFloat(this.toString()); // This could be something faster
        }; // end of Int128 section

        /*
        // Uncomment the following two lines if you want to use Int128 outside ClipperLib
        if (typeof(document) !== "undefined") window.Int128 = Int128;
        else self.Int128 = Int128;
        */
        // ---------------------------------------------  
        // Here starts the actual Clipper library:
        // Helper function to support Inheritance in Javascript


        if (typeof Inherit == 'undefined') {
          var Inherit = function Inherit(ce, ce2) {
            var p;

            if (typeof Object.getOwnPropertyNames == 'undefined') {
              for (p in ce2.prototype) if (typeof ce.prototype[p] == 'undefined' || ce.prototype[p] == Object.prototype[p]) ce.prototype[p] = ce2.prototype[p];

              for (p in ce2) if (typeof ce[p] == 'undefined') ce[p] = ce2[p];

              ce.$baseCtor = ce2;
            } else {
              var props = Object.getOwnPropertyNames(ce2.prototype);

              for (var i = 0; i < props.length; i++) if (typeof Object.getOwnPropertyDescriptor(ce.prototype, props[i]) == 'undefined') Object.defineProperty(ce.prototype, props[i], Object.getOwnPropertyDescriptor(ce2.prototype, props[i]));

              for (p in ce2) if (typeof ce[p] == 'undefined') ce[p] = ce2[p];

              ce.$baseCtor = ce2;
            }
          };
        }

        ClipperLib.Path = function () {
          return [];
        };

        ClipperLib.Paths = function () {
          return []; // Was previously [[]], but caused problems when pushed
        }; // Preserves the calling way of original C# Clipper
        // Is essential due to compatibility, because DoublePoint is public class in original C# version


        ClipperLib.DoublePoint = function () {
          var a = arguments;
          this.X = 0;
          this.Y = 0; // public DoublePoint(DoublePoint dp)
          // public DoublePoint(IntPoint ip)

          if (a.length == 1) {
            this.X = a[0].X;
            this.Y = a[0].Y;
          } else if (a.length == 2) {
            this.X = a[0];
            this.Y = a[1];
          }
        }; // This is internal faster function when called without arguments


        ClipperLib.DoublePoint0 = function () {
          this.X = 0;
          this.Y = 0;
        }; // This is internal faster function when called with 1 argument (dp or ip)


        ClipperLib.DoublePoint1 = function (dp) {
          this.X = dp.X;
          this.Y = dp.Y;
        }; // This is internal faster function when called with 2 arguments (x and y)


        ClipperLib.DoublePoint2 = function (x, y) {
          this.X = x;
          this.Y = y;
        }; // PolyTree & PolyNode start
        // -------------------------------


        ClipperLib.PolyNode = function () {
          this.m_Parent = null;
          this.m_polygon = new ClipperLib.Path();
          this.m_Index = 0;
          this.m_jointype = 0;
          this.m_endtype = 0;
          this.m_Childs = [];
          this.IsOpen = false;
        };

        ClipperLib.PolyNode.prototype.IsHoleNode = function () {
          var result = true;
          var node = this.m_Parent;

          while (node !== null) {
            result = !result;
            node = node.m_Parent;
          }

          return result;
        };

        ClipperLib.PolyNode.prototype.ChildCount = function () {
          return this.m_Childs.length;
        };

        ClipperLib.PolyNode.prototype.Contour = function () {
          return this.m_polygon;
        };

        ClipperLib.PolyNode.prototype.AddChild = function (Child) {
          var cnt = this.m_Childs.length;
          this.m_Childs.push(Child);
          Child.m_Parent = this;
          Child.m_Index = cnt;
        };

        ClipperLib.PolyNode.prototype.GetNext = function () {
          if (this.m_Childs.length > 0) return this.m_Childs[0];else return this.GetNextSiblingUp();
        };

        ClipperLib.PolyNode.prototype.GetNextSiblingUp = function () {
          if (this.m_Parent === null) return null;else if (this.m_Index == this.m_Parent.m_Childs.length - 1) return this.m_Parent.GetNextSiblingUp();else return this.m_Parent.m_Childs[this.m_Index + 1];
        };

        ClipperLib.PolyNode.prototype.Childs = function () {
          return this.m_Childs;
        };

        ClipperLib.PolyNode.prototype.Parent = function () {
          return this.m_Parent;
        };

        ClipperLib.PolyNode.prototype.IsHole = function () {
          return this.IsHoleNode();
        }; // PolyTree : PolyNode


        ClipperLib.PolyTree = function () {
          this.m_AllPolys = [];
          ClipperLib.PolyNode.call(this);
        };

        ClipperLib.PolyTree.prototype.Clear = function () {
          for (var i = 0, ilen = this.m_AllPolys.length; i < ilen; i++) this.m_AllPolys[i] = null;

          this.m_AllPolys.length = 0;
          this.m_Childs.length = 0;
        };

        ClipperLib.PolyTree.prototype.GetFirst = function () {
          if (this.m_Childs.length > 0) return this.m_Childs[0];else return null;
        };

        ClipperLib.PolyTree.prototype.Total = function () {
          return this.m_AllPolys.length;
        };

        Inherit(ClipperLib.PolyTree, ClipperLib.PolyNode); // -------------------------------
        // PolyTree & PolyNode end

        ClipperLib.Math_Abs_Int64 = ClipperLib.Math_Abs_Int32 = ClipperLib.Math_Abs_Double = function (a) {
          return Math.abs(a);
        };

        ClipperLib.Math_Max_Int32_Int32 = function (a, b) {
          return Math.max(a, b);
        };
        /*
        -----------------------------------
        cast_32 speedtest: http://jsperf.com/truncate-float-to-integer/2
        -----------------------------------
        */


        if (browser.msie || browser.opera || browser.safari) ClipperLib.Cast_Int32 = function (a) {
          return a | 0;
        };else ClipperLib.Cast_Int32 = function (a) {
          // eg. browser.chrome || browser.chromium || browser.firefox
          return ~~a;
        };
        /*
        --------------------------
        cast_64 speedtests: http://jsperf.com/truncate-float-to-integer
        Chrome: bitwise_not_floor
        Firefox17: toInteger (typeof test)
        IE9: bitwise_or_floor
        IE7 and IE8: to_parseint
        Chromium: to_floor_or_ceil
        Firefox3: to_floor_or_ceil
        Firefox15: to_floor_or_ceil
        Opera: to_floor_or_ceil
        Safari: to_floor_or_ceil
        --------------------------
        */

        if (browser.chrome) ClipperLib.Cast_Int64 = function (a) {
          if (a < -2147483648 || a > 2147483647) return a < 0 ? Math.ceil(a) : Math.floor(a);else return ~~a;
        };else if (browser.firefox && typeof Number.toInteger == "function") ClipperLib.Cast_Int64 = function (a) {
          return Number.toInteger(a);
        };else if (browser.msie7 || browser.msie8) ClipperLib.Cast_Int64 = function (a) {
          return parseInt(a, 10);
        };else if (browser.msie) ClipperLib.Cast_Int64 = function (a) {
          if (a < -2147483648 || a > 2147483647) return a < 0 ? Math.ceil(a) : Math.floor(a);
          return a | 0;
        }; // eg. browser.chromium || browser.firefox || browser.opera || browser.safari
        else ClipperLib.Cast_Int64 = function (a) {
            return a < 0 ? Math.ceil(a) : Math.floor(a);
          };

        ClipperLib.Clear = function (a) {
          a.length = 0;
        }; //ClipperLib.MaxSteps = 64; // How many steps at maximum in arc in BuildArc() function


        ClipperLib.PI = 3.141592653589793;
        ClipperLib.PI2 = 2 * 3.141592653589793;

        ClipperLib.IntPoint = function () {
          var a = arguments,
              alen = a.length;
          this.X = 0;
          this.Y = 0;
          var dp, pt;
          {
            if (alen == 2) // public IntPoint(cInt X, cInt Y)
              {
                this.X = a[0];
                this.Y = a[1];
              } else if (alen == 1) {
              if (a[0] instanceof ClipperLib.DoublePoint) // public IntPoint(DoublePoint dp)
                {
                  var dp = a[0];
                  this.X = ClipperLib.Clipper.Round(dp.X);
                  this.Y = ClipperLib.Clipper.Round(dp.Y);
                } else // public IntPoint(IntPoint pt)
                {
                  var pt = a[0];
                  this.X = pt.X;
                  this.Y = pt.Y;
                }
            } else // public IntPoint(IntPoint pt)
              {
                this.X = 0;
                this.Y = 0;
              }
          }
        };

        ClipperLib.IntPoint.op_Equality = function (a, b) {
          //return a == b;
          return a.X == b.X && a.Y == b.Y;
        };

        ClipperLib.IntPoint.op_Inequality = function (a, b) {
          //return a != b;
          return a.X != b.X || a.Y != b.Y;
        };
        /*
        ClipperLib.IntPoint.prototype.Equals = function (obj)
        {
          if (obj === null)
              return false;
          if (obj instanceof ClipperLib.IntPoint)
          {
              var a = Cast(obj, ClipperLib.IntPoint);
              return (this.X == a.X) && (this.Y == a.Y);
          }
          else
              return false;
        };
        */


        {
          ClipperLib.IntPoint0 = function () {
            this.X = 0;
            this.Y = 0;
          };

          ClipperLib.IntPoint1 = function (pt) {
            this.X = pt.X;
            this.Y = pt.Y;
          };

          ClipperLib.IntPoint1dp = function (dp) {
            this.X = ClipperLib.Clipper.Round(dp.X);
            this.Y = ClipperLib.Clipper.Round(dp.Y);
          };

          ClipperLib.IntPoint2 = function (x, y) {
            this.X = x;
            this.Y = y;
          };
        }

        ClipperLib.IntRect = function () {
          var a = arguments,
              alen = a.length;

          if (alen == 4) // function (l, t, r, b)
            {
              this.left = a[0];
              this.top = a[1];
              this.right = a[2];
              this.bottom = a[3];
            } else if (alen == 1) // function (ir)
            {
              this.left = ir.left;
              this.top = ir.top;
              this.right = ir.right;
              this.bottom = ir.bottom;
            } else // function ()
            {
              this.left = 0;
              this.top = 0;
              this.right = 0;
              this.bottom = 0;
            }
        };

        ClipperLib.IntRect0 = function () {
          this.left = 0;
          this.top = 0;
          this.right = 0;
          this.bottom = 0;
        };

        ClipperLib.IntRect1 = function (ir) {
          this.left = ir.left;
          this.top = ir.top;
          this.right = ir.right;
          this.bottom = ir.bottom;
        };

        ClipperLib.IntRect4 = function (l, t, r, b) {
          this.left = l;
          this.top = t;
          this.right = r;
          this.bottom = b;
        };

        ClipperLib.ClipType = {
          ctIntersection: 0,
          ctUnion: 1,
          ctDifference: 2,
          ctXor: 3
        };
        ClipperLib.PolyType = {
          ptSubject: 0,
          ptClip: 1
        };
        ClipperLib.PolyFillType = {
          pftEvenOdd: 0,
          pftNonZero: 1,
          pftPositive: 2,
          pftNegative: 3
        };
        ClipperLib.JoinType = {
          jtSquare: 0,
          jtRound: 1,
          jtMiter: 2
        };
        ClipperLib.EndType = {
          etOpenSquare: 0,
          etOpenRound: 1,
          etOpenButt: 2,
          etClosedLine: 3,
          etClosedPolygon: 4
        };
        ClipperLib.EdgeSide = {
          esLeft: 0,
          esRight: 1
        };
        ClipperLib.Direction = {
          dRightToLeft: 0,
          dLeftToRight: 1
        };

        ClipperLib.TEdge = function () {
          this.Bot = new ClipperLib.IntPoint();
          this.Curr = new ClipperLib.IntPoint();
          this.Top = new ClipperLib.IntPoint();
          this.Delta = new ClipperLib.IntPoint();
          this.Dx = 0;
          this.PolyTyp = ClipperLib.PolyType.ptSubject;
          this.Side = ClipperLib.EdgeSide.esLeft;
          this.WindDelta = 0;
          this.WindCnt = 0;
          this.WindCnt2 = 0;
          this.OutIdx = 0;
          this.Next = null;
          this.Prev = null;
          this.NextInLML = null;
          this.NextInAEL = null;
          this.PrevInAEL = null;
          this.NextInSEL = null;
          this.PrevInSEL = null;
        };

        ClipperLib.IntersectNode = function () {
          this.Edge1 = null;
          this.Edge2 = null;
          this.Pt = new ClipperLib.IntPoint();
        };

        ClipperLib.MyIntersectNodeSort = function () {};

        ClipperLib.MyIntersectNodeSort.Compare = function (node1, node2) {
          return node2.Pt.Y - node1.Pt.Y;
        };

        ClipperLib.LocalMinima = function () {
          this.Y = 0;
          this.LeftBound = null;
          this.RightBound = null;
          this.Next = null;
        };

        ClipperLib.Scanbeam = function () {
          this.Y = 0;
          this.Next = null;
        };

        ClipperLib.OutRec = function () {
          this.Idx = 0;
          this.IsHole = false;
          this.IsOpen = false;
          this.FirstLeft = null;
          this.Pts = null;
          this.BottomPt = null;
          this.PolyNode = null;
        };

        ClipperLib.OutPt = function () {
          this.Idx = 0;
          this.Pt = new ClipperLib.IntPoint();
          this.Next = null;
          this.Prev = null;
        };

        ClipperLib.Join = function () {
          this.OutPt1 = null;
          this.OutPt2 = null;
          this.OffPt = new ClipperLib.IntPoint();
        };

        ClipperLib.ClipperBase = function () {
          this.m_MinimaList = null;
          this.m_CurrentLM = null;
          this.m_edges = new Array();
          this.m_UseFullRange = false;
          this.m_HasOpenPaths = false;
          this.PreserveCollinear = false;
          this.m_MinimaList = null;
          this.m_CurrentLM = null;
          this.m_UseFullRange = false;
          this.m_HasOpenPaths = false;
        }; // Ranges are in original C# too high for Javascript (in current state 2013 september):
        // protected const double horizontal = -3.4E+38;
        // internal const cInt loRange = 0x3FFFFFFF; // = 1073741823 = sqrt(2^63 -1)/2
        // internal const cInt hiRange = 0x3FFFFFFFFFFFFFFFL; // = 4611686018427387903 = sqrt(2^127 -1)/2
        // So had to adjust them to more suitable for Javascript.
        // If JS some day supports truly 64-bit integers, then these ranges can be as in C#
        // and biginteger library can be more simpler (as then 128bit can be represented as two 64bit numbers)


        ClipperLib.ClipperBase.horizontal = -9007199254740992; //-2^53

        ClipperLib.ClipperBase.Skip = -2;
        ClipperLib.ClipperBase.Unassigned = -1;
        ClipperLib.ClipperBase.tolerance = 1E-20;
        {
          ClipperLib.ClipperBase.loRange = 47453132; // sqrt(2^53 -1)/2

          ClipperLib.ClipperBase.hiRange = 4503599627370495; // sqrt(2^106 -1)/2
        }

        ClipperLib.ClipperBase.near_zero = function (val) {
          return val > -ClipperLib.ClipperBase.tolerance && val < ClipperLib.ClipperBase.tolerance;
        };

        ClipperLib.ClipperBase.IsHorizontal = function (e) {
          return e.Delta.Y === 0;
        };

        ClipperLib.ClipperBase.prototype.PointIsVertex = function (pt, pp) {
          var pp2 = pp;

          do {
            if (ClipperLib.IntPoint.op_Equality(pp2.Pt, pt)) return true;
            pp2 = pp2.Next;
          } while (pp2 != pp);

          return false;
        };

        ClipperLib.ClipperBase.prototype.PointOnLineSegment = function (pt, linePt1, linePt2, UseFullRange) {
          if (UseFullRange) return pt.X == linePt1.X && pt.Y == linePt1.Y || pt.X == linePt2.X && pt.Y == linePt2.Y || pt.X > linePt1.X == pt.X < linePt2.X && pt.Y > linePt1.Y == pt.Y < linePt2.Y && Int128.op_Equality(Int128.Int128Mul(pt.X - linePt1.X, linePt2.Y - linePt1.Y), Int128.Int128Mul(linePt2.X - linePt1.X, pt.Y - linePt1.Y));else return pt.X == linePt1.X && pt.Y == linePt1.Y || pt.X == linePt2.X && pt.Y == linePt2.Y || pt.X > linePt1.X == pt.X < linePt2.X && pt.Y > linePt1.Y == pt.Y < linePt2.Y && (pt.X - linePt1.X) * (linePt2.Y - linePt1.Y) == (linePt2.X - linePt1.X) * (pt.Y - linePt1.Y);
        };

        ClipperLib.ClipperBase.prototype.PointOnPolygon = function (pt, pp, UseFullRange) {
          var pp2 = pp;

          while (true) {
            if (this.PointOnLineSegment(pt, pp2.Pt, pp2.Next.Pt, UseFullRange)) return true;
            pp2 = pp2.Next;
            if (pp2 == pp) break;
          }

          return false;
        };

        ClipperLib.ClipperBase.prototype.SlopesEqual = ClipperLib.ClipperBase.SlopesEqual = function () {
          var a = arguments,
              alen = a.length;
          var e1, e2, pt1, pt2, pt3, pt4, UseFullRange;

          if (alen == 3) // function (e1, e2, UseFullRange)
            {
              e1 = a[0];
              e2 = a[1];
              UseFullRange = a[2];
              if (UseFullRange) return Int128.op_Equality(Int128.Int128Mul(e1.Delta.Y, e2.Delta.X), Int128.Int128Mul(e1.Delta.X, e2.Delta.Y));else return ClipperLib.Cast_Int64(e1.Delta.Y * e2.Delta.X) == ClipperLib.Cast_Int64(e1.Delta.X * e2.Delta.Y);
            } else if (alen == 4) // function (pt1, pt2, pt3, UseFullRange)
            {
              pt1 = a[0];
              pt2 = a[1];
              pt3 = a[2];
              UseFullRange = a[3];
              if (UseFullRange) return Int128.op_Equality(Int128.Int128Mul(pt1.Y - pt2.Y, pt2.X - pt3.X), Int128.Int128Mul(pt1.X - pt2.X, pt2.Y - pt3.Y));else return ClipperLib.Cast_Int64((pt1.Y - pt2.Y) * (pt2.X - pt3.X)) - ClipperLib.Cast_Int64((pt1.X - pt2.X) * (pt2.Y - pt3.Y)) === 0;
            } else // function (pt1, pt2, pt3, pt4, UseFullRange)
            {
              pt1 = a[0];
              pt2 = a[1];
              pt3 = a[2];
              pt4 = a[3];
              UseFullRange = a[4];
              if (UseFullRange) return Int128.op_Equality(Int128.Int128Mul(pt1.Y - pt2.Y, pt3.X - pt4.X), Int128.Int128Mul(pt1.X - pt2.X, pt3.Y - pt4.Y));else return ClipperLib.Cast_Int64((pt1.Y - pt2.Y) * (pt3.X - pt4.X)) - ClipperLib.Cast_Int64((pt1.X - pt2.X) * (pt3.Y - pt4.Y)) === 0;
            }
        };

        ClipperLib.ClipperBase.SlopesEqual3 = function (e1, e2, UseFullRange) {
          if (UseFullRange) return Int128.op_Equality(Int128.Int128Mul(e1.Delta.Y, e2.Delta.X), Int128.Int128Mul(e1.Delta.X, e2.Delta.Y));else return ClipperLib.Cast_Int64(e1.Delta.Y * e2.Delta.X) == ClipperLib.Cast_Int64(e1.Delta.X * e2.Delta.Y);
        };

        ClipperLib.ClipperBase.SlopesEqual4 = function (pt1, pt2, pt3, UseFullRange) {
          if (UseFullRange) return Int128.op_Equality(Int128.Int128Mul(pt1.Y - pt2.Y, pt2.X - pt3.X), Int128.Int128Mul(pt1.X - pt2.X, pt2.Y - pt3.Y));else return ClipperLib.Cast_Int64((pt1.Y - pt2.Y) * (pt2.X - pt3.X)) - ClipperLib.Cast_Int64((pt1.X - pt2.X) * (pt2.Y - pt3.Y)) === 0;
        };

        ClipperLib.ClipperBase.SlopesEqual5 = function (pt1, pt2, pt3, pt4, UseFullRange) {
          if (UseFullRange) return Int128.op_Equality(Int128.Int128Mul(pt1.Y - pt2.Y, pt3.X - pt4.X), Int128.Int128Mul(pt1.X - pt2.X, pt3.Y - pt4.Y));else return ClipperLib.Cast_Int64((pt1.Y - pt2.Y) * (pt3.X - pt4.X)) - ClipperLib.Cast_Int64((pt1.X - pt2.X) * (pt3.Y - pt4.Y)) === 0;
        };

        ClipperLib.ClipperBase.prototype.Clear = function () {
          this.DisposeLocalMinimaList();

          for (var i = 0, ilen = this.m_edges.length; i < ilen; ++i) {
            for (var j = 0, jlen = this.m_edges[i].length; j < jlen; ++j) this.m_edges[i][j] = null;

            ClipperLib.Clear(this.m_edges[i]);
          }

          ClipperLib.Clear(this.m_edges);
          this.m_UseFullRange = false;
          this.m_HasOpenPaths = false;
        };

        ClipperLib.ClipperBase.prototype.DisposeLocalMinimaList = function () {
          while (this.m_MinimaList !== null) {
            var tmpLm = this.m_MinimaList.Next;
            this.m_MinimaList = null;
            this.m_MinimaList = tmpLm;
          }

          this.m_CurrentLM = null;
        };

        ClipperLib.ClipperBase.prototype.RangeTest = function (Pt, useFullRange) {
          if (useFullRange.Value) {
            if (Pt.X > ClipperLib.ClipperBase.hiRange || Pt.Y > ClipperLib.ClipperBase.hiRange || -Pt.X > ClipperLib.ClipperBase.hiRange || -Pt.Y > ClipperLib.ClipperBase.hiRange) ClipperLib.Error("Coordinate outside allowed range in RangeTest().");
          } else if (Pt.X > ClipperLib.ClipperBase.loRange || Pt.Y > ClipperLib.ClipperBase.loRange || -Pt.X > ClipperLib.ClipperBase.loRange || -Pt.Y > ClipperLib.ClipperBase.loRange) {
            useFullRange.Value = true;
            this.RangeTest(Pt, useFullRange);
          }
        };

        ClipperLib.ClipperBase.prototype.InitEdge = function (e, eNext, ePrev, pt) {
          e.Next = eNext;
          e.Prev = ePrev; //e.Curr = pt;

          e.Curr.X = pt.X;
          e.Curr.Y = pt.Y;
          e.OutIdx = -1;
        };

        ClipperLib.ClipperBase.prototype.InitEdge2 = function (e, polyType) {
          if (e.Curr.Y >= e.Next.Curr.Y) {
            //e.Bot = e.Curr;
            e.Bot.X = e.Curr.X;
            e.Bot.Y = e.Curr.Y; //e.Top = e.Next.Curr;

            e.Top.X = e.Next.Curr.X;
            e.Top.Y = e.Next.Curr.Y;
          } else {
            //e.Top = e.Curr;
            e.Top.X = e.Curr.X;
            e.Top.Y = e.Curr.Y; //e.Bot = e.Next.Curr;

            e.Bot.X = e.Next.Curr.X;
            e.Bot.Y = e.Next.Curr.Y;
          }

          this.SetDx(e);
          e.PolyTyp = polyType;
        };

        ClipperLib.ClipperBase.prototype.FindNextLocMin = function (E) {
          var E2;

          for (;;) {
            while (ClipperLib.IntPoint.op_Inequality(E.Bot, E.Prev.Bot) || ClipperLib.IntPoint.op_Equality(E.Curr, E.Top)) E = E.Next;

            if (E.Dx != ClipperLib.ClipperBase.horizontal && E.Prev.Dx != ClipperLib.ClipperBase.horizontal) break;

            while (E.Prev.Dx == ClipperLib.ClipperBase.horizontal) E = E.Prev;

            E2 = E;

            while (E.Dx == ClipperLib.ClipperBase.horizontal) E = E.Next;

            if (E.Top.Y == E.Prev.Bot.Y) continue; //ie just an intermediate horz.

            if (E2.Prev.Bot.X < E.Bot.X) E = E2;
            break;
          }

          return E;
        };

        ClipperLib.ClipperBase.prototype.ProcessBound = function (E, IsClockwise) {
          var EStart = E,
              Result = E;
          var Horz;
          var StartX;

          if (E.Dx == ClipperLib.ClipperBase.horizontal) {
            //it's possible for adjacent overlapping horz edges to start heading left
            //before finishing right, so ...
            if (IsClockwise) StartX = E.Prev.Bot.X;else StartX = E.Next.Bot.X;
            if (E.Bot.X != StartX) this.ReverseHorizontal(E);
          }

          if (Result.OutIdx != ClipperLib.ClipperBase.Skip) {
            if (IsClockwise) {
              while (Result.Top.Y == Result.Next.Bot.Y && Result.Next.OutIdx != ClipperLib.ClipperBase.Skip) Result = Result.Next;

              if (Result.Dx == ClipperLib.ClipperBase.horizontal && Result.Next.OutIdx != ClipperLib.ClipperBase.Skip) {
                //nb: at the top of a bound, horizontals are added to the bound
                //only when the preceding edge attaches to the horizontal's left vertex
                //unless a Skip edge is encountered when that becomes the top divide
                Horz = Result;

                while (Horz.Prev.Dx == ClipperLib.ClipperBase.horizontal) Horz = Horz.Prev;

                if (Horz.Prev.Top.X == Result.Next.Top.X) {
                  if (!IsClockwise) Result = Horz.Prev;
                } else if (Horz.Prev.Top.X > Result.Next.Top.X) Result = Horz.Prev;
              }

              while (E != Result) {
                E.NextInLML = E.Next;
                if (E.Dx == ClipperLib.ClipperBase.horizontal && E != EStart && E.Bot.X != E.Prev.Top.X) this.ReverseHorizontal(E);
                E = E.Next;
              }

              if (E.Dx == ClipperLib.ClipperBase.horizontal && E != EStart && E.Bot.X != E.Prev.Top.X) this.ReverseHorizontal(E);
              Result = Result.Next; //move to the edge just beyond current bound
            } else {
              while (Result.Top.Y == Result.Prev.Bot.Y && Result.Prev.OutIdx != ClipperLib.ClipperBase.Skip) Result = Result.Prev;

              if (Result.Dx == ClipperLib.ClipperBase.horizontal && Result.Prev.OutIdx != ClipperLib.ClipperBase.Skip) {
                Horz = Result;

                while (Horz.Next.Dx == ClipperLib.ClipperBase.horizontal) Horz = Horz.Next;

                if (Horz.Next.Top.X == Result.Prev.Top.X) {
                  if (!IsClockwise) Result = Horz.Next;
                } else if (Horz.Next.Top.X > Result.Prev.Top.X) Result = Horz.Next;
              }

              while (E != Result) {
                E.NextInLML = E.Prev;
                if (E.Dx == ClipperLib.ClipperBase.horizontal && E != EStart && E.Bot.X != E.Next.Top.X) this.ReverseHorizontal(E);
                E = E.Prev;
              }

              if (E.Dx == ClipperLib.ClipperBase.horizontal && E != EStart && E.Bot.X != E.Next.Top.X) this.ReverseHorizontal(E);
              Result = Result.Prev; //move to the edge just beyond current bound
            }
          }

          if (Result.OutIdx == ClipperLib.ClipperBase.Skip) {
            //if edges still remain in the current bound beyond the skip edge then
            //create another LocMin and call ProcessBound once more
            E = Result;

            if (IsClockwise) {
              while (E.Top.Y == E.Next.Bot.Y) E = E.Next; //don't include top horizontals when parsing a bound a second time,
              //they will be contained in the opposite bound ...


              while (E != Result && E.Dx == ClipperLib.ClipperBase.horizontal) E = E.Prev;
            } else {
              while (E.Top.Y == E.Prev.Bot.Y) E = E.Prev;

              while (E != Result && E.Dx == ClipperLib.ClipperBase.horizontal) E = E.Next;
            }

            if (E == Result) {
              if (IsClockwise) Result = E.Next;else Result = E.Prev;
            } else {
              //there are more edges in the bound beyond result starting with E
              if (IsClockwise) E = Result.Next;else E = Result.Prev;
              var locMin = new ClipperLib.LocalMinima();
              locMin.Next = null;
              locMin.Y = E.Bot.Y;
              locMin.LeftBound = null;
              locMin.RightBound = E;
              locMin.RightBound.WindDelta = 0;
              Result = this.ProcessBound(locMin.RightBound, IsClockwise);
              this.InsertLocalMinima(locMin);
            }
          }

          return Result;
        };

        ClipperLib.ClipperBase.prototype.AddPath = function (pg, polyType, Closed) {
          {
            if (!Closed && polyType == ClipperLib.PolyType.ptClip) ClipperLib.Error("AddPath: Open paths must be subject.");
          }
          var highI = pg.length - 1;
          if (Closed) while (highI > 0 && ClipperLib.IntPoint.op_Equality(pg[highI], pg[0])) --highI;

          while (highI > 0 && ClipperLib.IntPoint.op_Equality(pg[highI], pg[highI - 1])) --highI;

          if (Closed && highI < 2 || !Closed && highI < 1) return false; //create a new edge array ...

          var edges = new Array();

          for (var i = 0; i <= highI; i++) edges.push(new ClipperLib.TEdge());

          var IsFlat = true; //1. Basic (first) edge initialization ...
          //edges[1].Curr = pg[1];

          edges[1].Curr.X = pg[1].X;
          edges[1].Curr.Y = pg[1].Y;
          var $1 = {
            Value: this.m_UseFullRange
          };
          this.RangeTest(pg[0], $1);
          this.m_UseFullRange = $1.Value;
          $1.Value = this.m_UseFullRange;
          this.RangeTest(pg[highI], $1);
          this.m_UseFullRange = $1.Value;
          this.InitEdge(edges[0], edges[1], edges[highI], pg[0]);
          this.InitEdge(edges[highI], edges[0], edges[highI - 1], pg[highI]);

          for (var i = highI - 1; i >= 1; --i) {
            $1.Value = this.m_UseFullRange;
            this.RangeTest(pg[i], $1);
            this.m_UseFullRange = $1.Value;
            this.InitEdge(edges[i], edges[i + 1], edges[i - 1], pg[i]);
          }

          var eStart = edges[0]; //2. Remove duplicate vertices, and (when closed) collinear edges ...

          var E = eStart,
              eLoopStop = eStart;

          for (;;) {
            if (ClipperLib.IntPoint.op_Equality(E.Curr, E.Next.Curr)) {
              if (E == E.Next) break;
              if (E == eStart) eStart = E.Next;
              E = this.RemoveEdge(E);
              eLoopStop = E;
              continue;
            }

            if (E.Prev == E.Next) break;else if (Closed && ClipperLib.ClipperBase.SlopesEqual(E.Prev.Curr, E.Curr, E.Next.Curr, this.m_UseFullRange) && (!this.PreserveCollinear || !this.Pt2IsBetweenPt1AndPt3(E.Prev.Curr, E.Curr, E.Next.Curr))) {
              //Collinear edges are allowed for open paths but in closed paths
              //the default is to merge adjacent collinear edges into a single edge.
              //However, if the PreserveCollinear property is enabled, only overlapping
              //collinear edges (ie spikes) will be removed from closed paths.
              if (E == eStart) eStart = E.Next;
              E = this.RemoveEdge(E);
              E = E.Prev;
              eLoopStop = E;
              continue;
            }
            E = E.Next;
            if (E == eLoopStop) break;
          }

          if (!Closed && E == E.Next || Closed && E.Prev == E.Next) return false;

          if (!Closed) {
            this.m_HasOpenPaths = true;
            eStart.Prev.OutIdx = ClipperLib.ClipperBase.Skip;
          }

          E = eStart;

          do {
            this.InitEdge2(E, polyType);
            E = E.Next;
            if (IsFlat && E.Curr.Y != eStart.Curr.Y) IsFlat = false;
          } while (E != eStart); //4. Finally, add edge bounds to LocalMinima list ...
          //Totally flat paths must be handled differently when adding them
          //to LocalMinima list to avoid endless loops etc ...


          if (IsFlat) {
            if (Closed) return false;
            E.Prev.OutIdx = ClipperLib.ClipperBase.Skip;
            if (E.Prev.Bot.X < E.Prev.Top.X) this.ReverseHorizontal(E.Prev);
            var locMin = new ClipperLib.LocalMinima();
            locMin.Next = null;
            locMin.Y = E.Bot.Y;
            locMin.LeftBound = null;
            locMin.RightBound = E;
            locMin.RightBound.Side = ClipperLib.EdgeSide.esRight;
            locMin.RightBound.WindDelta = 0;

            while (E.Next.OutIdx != ClipperLib.ClipperBase.Skip) {
              E.NextInLML = E.Next;
              if (E.Bot.X != E.Prev.Top.X) this.ReverseHorizontal(E);
              E = E.Next;
            }

            this.InsertLocalMinima(locMin);
            this.m_edges.push(edges);
            return true;
          }

          this.m_edges.push(edges);
          var clockwise;
          var EMin = null;

          for (;;) {
            E = this.FindNextLocMin(E);
            if (E == EMin) break;else if (EMin == null) EMin = E; //E and E.Prev now share a local minima (left aligned if horizontal).
            //Compare their slopes to find which starts which bound ...

            var locMin = new ClipperLib.LocalMinima();
            locMin.Next = null;
            locMin.Y = E.Bot.Y;

            if (E.Dx < E.Prev.Dx) {
              locMin.LeftBound = E.Prev;
              locMin.RightBound = E;
              clockwise = false; //Q.nextInLML = Q.prev
            } else {
              locMin.LeftBound = E;
              locMin.RightBound = E.Prev;
              clockwise = true; //Q.nextInLML = Q.next
            }

            locMin.LeftBound.Side = ClipperLib.EdgeSide.esLeft;
            locMin.RightBound.Side = ClipperLib.EdgeSide.esRight;
            if (!Closed) locMin.LeftBound.WindDelta = 0;else if (locMin.LeftBound.Next == locMin.RightBound) locMin.LeftBound.WindDelta = -1;else locMin.LeftBound.WindDelta = 1;
            locMin.RightBound.WindDelta = -locMin.LeftBound.WindDelta;
            E = this.ProcessBound(locMin.LeftBound, clockwise);
            var E2 = this.ProcessBound(locMin.RightBound, !clockwise);
            if (locMin.LeftBound.OutIdx == ClipperLib.ClipperBase.Skip) locMin.LeftBound = null;else if (locMin.RightBound.OutIdx == ClipperLib.ClipperBase.Skip) locMin.RightBound = null;
            this.InsertLocalMinima(locMin);
            if (!clockwise) E = E2;
          }

          return true;
        };

        ClipperLib.ClipperBase.prototype.AddPaths = function (ppg, polyType, closed) {
          //  console.log("-------------------------------------------");
          //  console.log(JSON.stringify(ppg));
          var result = false;

          for (var i = 0, ilen = ppg.length; i < ilen; ++i) if (this.AddPath(ppg[i], polyType, closed)) result = true;

          return result;
        }; //------------------------------------------------------------------------------


        ClipperLib.ClipperBase.prototype.Pt2IsBetweenPt1AndPt3 = function (pt1, pt2, pt3) {
          if (ClipperLib.IntPoint.op_Equality(pt1, pt3) || ClipperLib.IntPoint.op_Equality(pt1, pt2) || ClipperLib.IntPoint.op_Equality(pt3, pt2)) return false;else if (pt1.X != pt3.X) return pt2.X > pt1.X == pt2.X < pt3.X;else return pt2.Y > pt1.Y == pt2.Y < pt3.Y;
        };

        ClipperLib.ClipperBase.prototype.RemoveEdge = function (e) {
          //removes e from double_linked_list (but without removing from memory)
          e.Prev.Next = e.Next;
          e.Next.Prev = e.Prev;
          var result = e.Next;
          e.Prev = null; //flag as removed (see ClipperBase.Clear)

          return result;
        };

        ClipperLib.ClipperBase.prototype.SetDx = function (e) {
          e.Delta.X = e.Top.X - e.Bot.X;
          e.Delta.Y = e.Top.Y - e.Bot.Y;
          if (e.Delta.Y === 0) e.Dx = ClipperLib.ClipperBase.horizontal;else e.Dx = e.Delta.X / e.Delta.Y;
        };

        ClipperLib.ClipperBase.prototype.InsertLocalMinima = function (newLm) {
          if (this.m_MinimaList === null) {
            this.m_MinimaList = newLm;
          } else if (newLm.Y >= this.m_MinimaList.Y) {
            newLm.Next = this.m_MinimaList;
            this.m_MinimaList = newLm;
          } else {
            var tmpLm = this.m_MinimaList;

            while (tmpLm.Next !== null && newLm.Y < tmpLm.Next.Y) tmpLm = tmpLm.Next;

            newLm.Next = tmpLm.Next;
            tmpLm.Next = newLm;
          }
        };

        ClipperLib.ClipperBase.prototype.PopLocalMinima = function () {
          if (this.m_CurrentLM === null) return;
          this.m_CurrentLM = this.m_CurrentLM.Next;
        };

        ClipperLib.ClipperBase.prototype.ReverseHorizontal = function (e) {
          //swap horizontal edges' top and bottom x's so they follow the natural
          //progression of the bounds - ie so their xbots will align with the
          //adjoining lower edge. [Helpful in the ProcessHorizontal() method.]
          var tmp = e.Top.X;
          e.Top.X = e.Bot.X;
          e.Bot.X = tmp;
        };

        ClipperLib.ClipperBase.prototype.Reset = function () {
          this.m_CurrentLM = this.m_MinimaList;
          if (this.m_CurrentLM == null) return; //ie nothing to process
          //reset all edges ...

          var lm = this.m_MinimaList;

          while (lm != null) {
            var e = lm.LeftBound;

            if (e != null) {
              //e.Curr = e.Bot;
              e.Curr.X = e.Bot.X;
              e.Curr.Y = e.Bot.Y;
              e.Side = ClipperLib.EdgeSide.esLeft;
              e.OutIdx = ClipperLib.ClipperBase.Unassigned;
            }

            e = lm.RightBound;

            if (e != null) {
              //e.Curr = e.Bot;
              e.Curr.X = e.Bot.X;
              e.Curr.Y = e.Bot.Y;
              e.Side = ClipperLib.EdgeSide.esRight;
              e.OutIdx = ClipperLib.ClipperBase.Unassigned;
            }

            lm = lm.Next;
          }
        };

        ClipperLib.Clipper = function (InitOptions) // public Clipper(int InitOptions = 0)
        {
          if (typeof InitOptions == "undefined") InitOptions = 0;
          this.m_PolyOuts = null;
          this.m_ClipType = ClipperLib.ClipType.ctIntersection;
          this.m_Scanbeam = null;
          this.m_ActiveEdges = null;
          this.m_SortedEdges = null;
          this.m_IntersectList = null;
          this.m_IntersectNodeComparer = null;
          this.m_ExecuteLocked = false;
          this.m_ClipFillType = ClipperLib.PolyFillType.pftEvenOdd;
          this.m_SubjFillType = ClipperLib.PolyFillType.pftEvenOdd;
          this.m_Joins = null;
          this.m_GhostJoins = null;
          this.m_UsingPolyTree = false;
          this.ReverseSolution = false;
          this.StrictlySimple = false;
          ClipperLib.ClipperBase.call(this);
          this.m_Scanbeam = null;
          this.m_ActiveEdges = null;
          this.m_SortedEdges = null;
          this.m_IntersectList = new Array();
          this.m_IntersectNodeComparer = ClipperLib.MyIntersectNodeSort.Compare;
          this.m_ExecuteLocked = false;
          this.m_UsingPolyTree = false;
          this.m_PolyOuts = new Array();
          this.m_Joins = new Array();
          this.m_GhostJoins = new Array();
          this.ReverseSolution = (1 & InitOptions) !== 0;
          this.StrictlySimple = (2 & InitOptions) !== 0;
          this.PreserveCollinear = (4 & InitOptions) !== 0;
        };

        ClipperLib.Clipper.ioReverseSolution = 1;
        ClipperLib.Clipper.ioStrictlySimple = 2;
        ClipperLib.Clipper.ioPreserveCollinear = 4;

        ClipperLib.Clipper.prototype.Clear = function () {
          if (this.m_edges.length === 0) return; //avoids problems with ClipperBase destructor

          this.DisposeAllPolyPts();
          ClipperLib.ClipperBase.prototype.Clear.call(this);
        };

        ClipperLib.Clipper.prototype.DisposeScanbeamList = function () {
          while (this.m_Scanbeam !== null) {
            var sb2 = this.m_Scanbeam.Next;
            this.m_Scanbeam = null;
            this.m_Scanbeam = sb2;
          }
        };

        ClipperLib.Clipper.prototype.Reset = function () {
          ClipperLib.ClipperBase.prototype.Reset.call(this);
          this.m_Scanbeam = null;
          this.m_ActiveEdges = null;
          this.m_SortedEdges = null;
          var lm = this.m_MinimaList;

          while (lm !== null) {
            this.InsertScanbeam(lm.Y);
            lm = lm.Next;
          }
        };

        ClipperLib.Clipper.prototype.InsertScanbeam = function (Y) {
          if (this.m_Scanbeam === null) {
            this.m_Scanbeam = new ClipperLib.Scanbeam();
            this.m_Scanbeam.Next = null;
            this.m_Scanbeam.Y = Y;
          } else if (Y > this.m_Scanbeam.Y) {
            var newSb = new ClipperLib.Scanbeam();
            newSb.Y = Y;
            newSb.Next = this.m_Scanbeam;
            this.m_Scanbeam = newSb;
          } else {
            var sb2 = this.m_Scanbeam;

            while (sb2.Next !== null && Y <= sb2.Next.Y) sb2 = sb2.Next;

            if (Y == sb2.Y) return; //ie ignores duplicates

            var newSb = new ClipperLib.Scanbeam();
            newSb.Y = Y;
            newSb.Next = sb2.Next;
            sb2.Next = newSb;
          }
        }; // ************************************


        ClipperLib.Clipper.prototype.Execute = function () {
          var a = arguments,
              alen = a.length,
              ispolytree = a[1] instanceof ClipperLib.PolyTree;

          if (alen == 4 && !ispolytree) // function (clipType, solution, subjFillType, clipFillType)
            {
              var clipType = a[0],
                  solution = a[1],
                  subjFillType = a[2],
                  clipFillType = a[3];
              if (this.m_ExecuteLocked) return false;
              if (this.m_HasOpenPaths) ClipperLib.Error("Error: PolyTree struct is need for open path clipping.");
              this.m_ExecuteLocked = true;
              ClipperLib.Clear(solution);
              this.m_SubjFillType = subjFillType;
              this.m_ClipFillType = clipFillType;
              this.m_ClipType = clipType;
              this.m_UsingPolyTree = false;

              try {
                var succeeded = this.ExecuteInternal(); //build the return polygons ...

                if (succeeded) this.BuildResult(solution);
              } finally {
                this.DisposeAllPolyPts();
                this.m_ExecuteLocked = false;
              }

              return succeeded;
            } else if (alen == 4 && ispolytree) // function (clipType, polytree, subjFillType, clipFillType)
            {
              var clipType = a[0],
                  polytree = a[1],
                  subjFillType = a[2],
                  clipFillType = a[3];
              if (this.m_ExecuteLocked) return false;
              this.m_ExecuteLocked = true;
              this.m_SubjFillType = subjFillType;
              this.m_ClipFillType = clipFillType;
              this.m_ClipType = clipType;
              this.m_UsingPolyTree = true;

              try {
                var succeeded = this.ExecuteInternal(); //build the return polygons ...

                if (succeeded) this.BuildResult2(polytree);
              } finally {
                this.DisposeAllPolyPts();
                this.m_ExecuteLocked = false;
              }

              return succeeded;
            } else if (alen == 2 && !ispolytree) // function (clipType, solution)
            {
              var clipType = a[0],
                  solution = a[1];
              return this.Execute(clipType, solution, ClipperLib.PolyFillType.pftEvenOdd, ClipperLib.PolyFillType.pftEvenOdd);
            } else if (alen == 2 && ispolytree) // function (clipType, polytree)
            {
              var clipType = a[0],
                  polytree = a[1];
              return this.Execute(clipType, polytree, ClipperLib.PolyFillType.pftEvenOdd, ClipperLib.PolyFillType.pftEvenOdd);
            }
        };

        ClipperLib.Clipper.prototype.FixHoleLinkage = function (outRec) {
          //skip if an outermost polygon or
          //already already points to the correct FirstLeft ...
          if (outRec.FirstLeft === null || outRec.IsHole != outRec.FirstLeft.IsHole && outRec.FirstLeft.Pts !== null) return;
          var orfl = outRec.FirstLeft;

          while (orfl !== null && (orfl.IsHole == outRec.IsHole || orfl.Pts === null)) orfl = orfl.FirstLeft;

          outRec.FirstLeft = orfl;
        };

        ClipperLib.Clipper.prototype.ExecuteInternal = function () {
          try {
            this.Reset();
            if (this.m_CurrentLM === null) return false;
            var botY = this.PopScanbeam();

            do {
              this.InsertLocalMinimaIntoAEL(botY);
              ClipperLib.Clear(this.m_GhostJoins);
              this.ProcessHorizontals(false);
              if (this.m_Scanbeam === null) break;
              var topY = this.PopScanbeam(); //console.log("botY:" + botY + ", topY:" + topY);

              if (!this.ProcessIntersections(botY, topY)) return false;
              this.ProcessEdgesAtTopOfScanbeam(topY);
              botY = topY;
            } while (this.m_Scanbeam !== null || this.m_CurrentLM !== null); //fix orientations ...


            for (var i = 0, ilen = this.m_PolyOuts.length; i < ilen; i++) {
              var outRec = this.m_PolyOuts[i];
              if (outRec.Pts === null || outRec.IsOpen) continue;
              if ((outRec.IsHole ^ this.ReverseSolution) == this.Area(outRec) > 0) this.ReversePolyPtLinks(outRec.Pts);
            }

            this.JoinCommonEdges();

            for (var i = 0, ilen = this.m_PolyOuts.length; i < ilen; i++) {
              var outRec = this.m_PolyOuts[i];
              if (outRec.Pts !== null && !outRec.IsOpen) this.FixupOutPolygon(outRec);
            }

            if (this.StrictlySimple) this.DoSimplePolygons();
            return true;
          } finally {
            ClipperLib.Clear(this.m_Joins);
            ClipperLib.Clear(this.m_GhostJoins);
          }
        };

        ClipperLib.Clipper.prototype.PopScanbeam = function () {
          var Y = this.m_Scanbeam.Y;
          var sb2 = this.m_Scanbeam;
          this.m_Scanbeam = this.m_Scanbeam.Next;
          sb2 = null;
          return Y;
        };

        ClipperLib.Clipper.prototype.DisposeAllPolyPts = function () {
          for (var i = 0, ilen = this.m_PolyOuts.length; i < ilen; ++i) this.DisposeOutRec(i);

          ClipperLib.Clear(this.m_PolyOuts);
        };

        ClipperLib.Clipper.prototype.DisposeOutRec = function (index) {
          var outRec = this.m_PolyOuts[index];
          if (outRec.Pts !== null) this.DisposeOutPts(outRec.Pts);
          outRec = null;
          this.m_PolyOuts[index] = null;
        };

        ClipperLib.Clipper.prototype.DisposeOutPts = function (pp) {
          if (pp === null) return;
          pp.Prev.Next = null;

          while (pp !== null) {
            pp = pp.Next;
          }
        };

        ClipperLib.Clipper.prototype.AddJoin = function (Op1, Op2, OffPt) {
          var j = new ClipperLib.Join();
          j.OutPt1 = Op1;
          j.OutPt2 = Op2; //j.OffPt = OffPt;

          j.OffPt.X = OffPt.X;
          j.OffPt.Y = OffPt.Y;
          this.m_Joins.push(j);
        };

        ClipperLib.Clipper.prototype.AddGhostJoin = function (Op, OffPt) {
          var j = new ClipperLib.Join();
          j.OutPt1 = Op; //j.OffPt = OffPt;

          j.OffPt.X = OffPt.X;
          j.OffPt.Y = OffPt.Y;
          this.m_GhostJoins.push(j);
        };

        ClipperLib.Clipper.prototype.InsertLocalMinimaIntoAEL = function (botY) {
          while (this.m_CurrentLM !== null && this.m_CurrentLM.Y == botY) {
            var lb = this.m_CurrentLM.LeftBound;
            var rb = this.m_CurrentLM.RightBound;
            this.PopLocalMinima();
            var Op1 = null;

            if (lb === null) {
              this.InsertEdgeIntoAEL(rb, null);
              this.SetWindingCount(rb);
              if (this.IsContributing(rb)) Op1 = this.AddOutPt(rb, rb.Bot);
            } else if (rb == null) {
              this.InsertEdgeIntoAEL(lb, null);
              this.SetWindingCount(lb);
              if (this.IsContributing(lb)) Op1 = this.AddOutPt(lb, lb.Bot);
              this.InsertScanbeam(lb.Top.Y);
            } else {
              this.InsertEdgeIntoAEL(lb, null);
              this.InsertEdgeIntoAEL(rb, lb);
              this.SetWindingCount(lb);
              rb.WindCnt = lb.WindCnt;
              rb.WindCnt2 = lb.WindCnt2;
              if (this.IsContributing(lb)) Op1 = this.AddLocalMinPoly(lb, rb, lb.Bot);
              this.InsertScanbeam(lb.Top.Y);
            }

            if (rb != null) {
              if (ClipperLib.ClipperBase.IsHorizontal(rb)) this.AddEdgeToSEL(rb);else this.InsertScanbeam(rb.Top.Y);
            }

            if (lb == null || rb == null) continue; //if output polygons share an Edge with a horizontal rb, they'll need joining later ...

            if (Op1 !== null && ClipperLib.ClipperBase.IsHorizontal(rb) && this.m_GhostJoins.length > 0 && rb.WindDelta !== 0) {
              for (var i = 0, ilen = this.m_GhostJoins.length; i < ilen; i++) {
                //if the horizontal Rb and a 'ghost' horizontal overlap, then convert
                //the 'ghost' join to a real join ready for later ...
                var j = this.m_GhostJoins[i];
                if (this.HorzSegmentsOverlap(j.OutPt1.Pt, j.OffPt, rb.Bot, rb.Top)) this.AddJoin(j.OutPt1, Op1, j.OffPt);
              }
            }

            if (lb.OutIdx >= 0 && lb.PrevInAEL !== null && lb.PrevInAEL.Curr.X == lb.Bot.X && lb.PrevInAEL.OutIdx >= 0 && ClipperLib.ClipperBase.SlopesEqual(lb.PrevInAEL, lb, this.m_UseFullRange) && lb.WindDelta !== 0 && lb.PrevInAEL.WindDelta !== 0) {
              var Op2 = this.AddOutPt(lb.PrevInAEL, lb.Bot);
              this.AddJoin(Op1, Op2, lb.Top);
            }

            if (lb.NextInAEL != rb) {
              if (rb.OutIdx >= 0 && rb.PrevInAEL.OutIdx >= 0 && ClipperLib.ClipperBase.SlopesEqual(rb.PrevInAEL, rb, this.m_UseFullRange) && rb.WindDelta !== 0 && rb.PrevInAEL.WindDelta !== 0) {
                var Op2 = this.AddOutPt(rb.PrevInAEL, rb.Bot);
                this.AddJoin(Op1, Op2, rb.Top);
              }

              var e = lb.NextInAEL;
              if (e !== null) while (e != rb) {
                //nb: For calculating winding counts etc, IntersectEdges() assumes
                //that param1 will be to the right of param2 ABOVE the intersection ...
                this.IntersectEdges(rb, e, lb.Curr, false); //order important here

                e = e.NextInAEL;
              }
            }
          }
        };

        ClipperLib.Clipper.prototype.InsertEdgeIntoAEL = function (edge, startEdge) {
          if (this.m_ActiveEdges === null) {
            edge.PrevInAEL = null;
            edge.NextInAEL = null;
            this.m_ActiveEdges = edge;
          } else if (startEdge === null && this.E2InsertsBeforeE1(this.m_ActiveEdges, edge)) {
            edge.PrevInAEL = null;
            edge.NextInAEL = this.m_ActiveEdges;
            this.m_ActiveEdges.PrevInAEL = edge;
            this.m_ActiveEdges = edge;
          } else {
            if (startEdge === null) startEdge = this.m_ActiveEdges;

            while (startEdge.NextInAEL !== null && !this.E2InsertsBeforeE1(startEdge.NextInAEL, edge)) startEdge = startEdge.NextInAEL;

            edge.NextInAEL = startEdge.NextInAEL;
            if (startEdge.NextInAEL !== null) startEdge.NextInAEL.PrevInAEL = edge;
            edge.PrevInAEL = startEdge;
            startEdge.NextInAEL = edge;
          }
        };

        ClipperLib.Clipper.prototype.E2InsertsBeforeE1 = function (e1, e2) {
          if (e2.Curr.X == e1.Curr.X) {
            if (e2.Top.Y > e1.Top.Y) return e2.Top.X < ClipperLib.Clipper.TopX(e1, e2.Top.Y);else return e1.Top.X > ClipperLib.Clipper.TopX(e2, e1.Top.Y);
          } else return e2.Curr.X < e1.Curr.X;
        };

        ClipperLib.Clipper.prototype.IsEvenOddFillType = function (edge) {
          if (edge.PolyTyp == ClipperLib.PolyType.ptSubject) return this.m_SubjFillType == ClipperLib.PolyFillType.pftEvenOdd;else return this.m_ClipFillType == ClipperLib.PolyFillType.pftEvenOdd;
        };

        ClipperLib.Clipper.prototype.IsEvenOddAltFillType = function (edge) {
          if (edge.PolyTyp == ClipperLib.PolyType.ptSubject) return this.m_ClipFillType == ClipperLib.PolyFillType.pftEvenOdd;else return this.m_SubjFillType == ClipperLib.PolyFillType.pftEvenOdd;
        };

        ClipperLib.Clipper.prototype.IsContributing = function (edge) {
          var pft, pft2;

          if (edge.PolyTyp == ClipperLib.PolyType.ptSubject) {
            pft = this.m_SubjFillType;
            pft2 = this.m_ClipFillType;
          } else {
            pft = this.m_ClipFillType;
            pft2 = this.m_SubjFillType;
          }

          switch (pft) {
            case ClipperLib.PolyFillType.pftEvenOdd:
              if (edge.WindDelta === 0 && edge.WindCnt != 1) return false;
              break;

            case ClipperLib.PolyFillType.pftNonZero:
              if (Math.abs(edge.WindCnt) != 1) return false;
              break;

            case ClipperLib.PolyFillType.pftPositive:
              if (edge.WindCnt != 1) return false;
              break;

            default:
              if (edge.WindCnt != -1) return false;
              break;
          }

          switch (this.m_ClipType) {
            case ClipperLib.ClipType.ctIntersection:
              switch (pft2) {
                case ClipperLib.PolyFillType.pftEvenOdd:
                case ClipperLib.PolyFillType.pftNonZero:
                  return edge.WindCnt2 !== 0;

                case ClipperLib.PolyFillType.pftPositive:
                  return edge.WindCnt2 > 0;

                default:
                  return edge.WindCnt2 < 0;
              }

            case ClipperLib.ClipType.ctUnion:
              switch (pft2) {
                case ClipperLib.PolyFillType.pftEvenOdd:
                case ClipperLib.PolyFillType.pftNonZero:
                  return edge.WindCnt2 === 0;

                case ClipperLib.PolyFillType.pftPositive:
                  return edge.WindCnt2 <= 0;

                default:
                  return edge.WindCnt2 >= 0;
              }

            case ClipperLib.ClipType.ctDifference:
              if (edge.PolyTyp == ClipperLib.PolyType.ptSubject) switch (pft2) {
                case ClipperLib.PolyFillType.pftEvenOdd:
                case ClipperLib.PolyFillType.pftNonZero:
                  return edge.WindCnt2 === 0;

                case ClipperLib.PolyFillType.pftPositive:
                  return edge.WindCnt2 <= 0;

                default:
                  return edge.WindCnt2 >= 0;
              } else switch (pft2) {
                case ClipperLib.PolyFillType.pftEvenOdd:
                case ClipperLib.PolyFillType.pftNonZero:
                  return edge.WindCnt2 !== 0;

                case ClipperLib.PolyFillType.pftPositive:
                  return edge.WindCnt2 > 0;

                default:
                  return edge.WindCnt2 < 0;
              }

            case ClipperLib.ClipType.ctXor:
              if (edge.WindDelta === 0) switch (pft2) {
                case ClipperLib.PolyFillType.pftEvenOdd:
                case ClipperLib.PolyFillType.pftNonZero:
                  return edge.WindCnt2 === 0;

                case ClipperLib.PolyFillType.pftPositive:
                  return edge.WindCnt2 <= 0;

                default:
                  return edge.WindCnt2 >= 0;
              } else return true;
          }

          return true;
        };

        ClipperLib.Clipper.prototype.SetWindingCount = function (edge) {
          var e = edge.PrevInAEL; //find the edge of the same polytype that immediately preceeds 'edge' in AEL

          while (e !== null && (e.PolyTyp != edge.PolyTyp || e.WindDelta === 0)) e = e.PrevInAEL;

          if (e === null) {
            edge.WindCnt = edge.WindDelta === 0 ? 1 : edge.WindDelta;
            edge.WindCnt2 = 0;
            e = this.m_ActiveEdges; //ie get ready to calc WindCnt2
          } else if (edge.WindDelta === 0 && this.m_ClipType != ClipperLib.ClipType.ctUnion) {
            edge.WindCnt = 1;
            edge.WindCnt2 = e.WindCnt2;
            e = e.NextInAEL; //ie get ready to calc WindCnt2
          } else if (this.IsEvenOddFillType(edge)) {
            //EvenOdd filling ...
            if (edge.WindDelta === 0) {
              //are we inside a subj polygon ...
              var Inside = true;
              var e2 = e.PrevInAEL;

              while (e2 !== null) {
                if (e2.PolyTyp == e.PolyTyp && e2.WindDelta !== 0) Inside = !Inside;
                e2 = e2.PrevInAEL;
              }

              edge.WindCnt = Inside ? 0 : 1;
            } else {
              edge.WindCnt = edge.WindDelta;
            }

            edge.WindCnt2 = e.WindCnt2;
            e = e.NextInAEL; //ie get ready to calc WindCnt2
          } else {
            //nonZero, Positive or Negative filling ...
            if (e.WindCnt * e.WindDelta < 0) {
              //prev edge is 'decreasing' WindCount (WC) toward zero
              //so we're outside the previous polygon ...
              if (Math.abs(e.WindCnt) > 1) {
                //outside prev poly but still inside another.
                //when reversing direction of prev poly use the same WC 
                if (e.WindDelta * edge.WindDelta < 0) edge.WindCnt = e.WindCnt;else edge.WindCnt = e.WindCnt + edge.WindDelta;
              } else edge.WindCnt = edge.WindDelta === 0 ? 1 : edge.WindDelta;
            } else {
              //prev edge is 'increasing' WindCount (WC) away from zero
              //so we're inside the previous polygon ...
              if (edge.WindDelta === 0) edge.WindCnt = e.WindCnt < 0 ? e.WindCnt - 1 : e.WindCnt + 1;else if (e.WindDelta * edge.WindDelta < 0) edge.WindCnt = e.WindCnt;else edge.WindCnt = e.WindCnt + edge.WindDelta;
            }

            edge.WindCnt2 = e.WindCnt2;
            e = e.NextInAEL; //ie get ready to calc WindCnt2
          } //update WindCnt2 ...


          if (this.IsEvenOddAltFillType(edge)) {
            //EvenOdd filling ...
            while (e != edge) {
              if (e.WindDelta !== 0) edge.WindCnt2 = edge.WindCnt2 === 0 ? 1 : 0;
              e = e.NextInAEL;
            }
          } else {
            //nonZero, Positive or Negative filling ...
            while (e != edge) {
              edge.WindCnt2 += e.WindDelta;
              e = e.NextInAEL;
            }
          }
        };

        ClipperLib.Clipper.prototype.AddEdgeToSEL = function (edge) {
          //SEL pointers in PEdge are reused to build a list of horizontal edges.
          //However, we don't need to worry about order with horizontal edge processing.
          if (this.m_SortedEdges === null) {
            this.m_SortedEdges = edge;
            edge.PrevInSEL = null;
            edge.NextInSEL = null;
          } else {
            edge.NextInSEL = this.m_SortedEdges;
            edge.PrevInSEL = null;
            this.m_SortedEdges.PrevInSEL = edge;
            this.m_SortedEdges = edge;
          }
        };

        ClipperLib.Clipper.prototype.CopyAELToSEL = function () {
          var e = this.m_ActiveEdges;
          this.m_SortedEdges = e;

          while (e !== null) {
            e.PrevInSEL = e.PrevInAEL;
            e.NextInSEL = e.NextInAEL;
            e = e.NextInAEL;
          }
        };

        ClipperLib.Clipper.prototype.SwapPositionsInAEL = function (edge1, edge2) {
          //check that one or other edge hasn't already been removed from AEL ...
          if (edge1.NextInAEL == edge1.PrevInAEL || edge2.NextInAEL == edge2.PrevInAEL) return;

          if (edge1.NextInAEL == edge2) {
            var next = edge2.NextInAEL;
            if (next !== null) next.PrevInAEL = edge1;
            var prev = edge1.PrevInAEL;
            if (prev !== null) prev.NextInAEL = edge2;
            edge2.PrevInAEL = prev;
            edge2.NextInAEL = edge1;
            edge1.PrevInAEL = edge2;
            edge1.NextInAEL = next;
          } else if (edge2.NextInAEL == edge1) {
            var next = edge1.NextInAEL;
            if (next !== null) next.PrevInAEL = edge2;
            var prev = edge2.PrevInAEL;
            if (prev !== null) prev.NextInAEL = edge1;
            edge1.PrevInAEL = prev;
            edge1.NextInAEL = edge2;
            edge2.PrevInAEL = edge1;
            edge2.NextInAEL = next;
          } else {
            var next = edge1.NextInAEL;
            var prev = edge1.PrevInAEL;
            edge1.NextInAEL = edge2.NextInAEL;
            if (edge1.NextInAEL !== null) edge1.NextInAEL.PrevInAEL = edge1;
            edge1.PrevInAEL = edge2.PrevInAEL;
            if (edge1.PrevInAEL !== null) edge1.PrevInAEL.NextInAEL = edge1;
            edge2.NextInAEL = next;
            if (edge2.NextInAEL !== null) edge2.NextInAEL.PrevInAEL = edge2;
            edge2.PrevInAEL = prev;
            if (edge2.PrevInAEL !== null) edge2.PrevInAEL.NextInAEL = edge2;
          }

          if (edge1.PrevInAEL === null) this.m_ActiveEdges = edge1;else if (edge2.PrevInAEL === null) this.m_ActiveEdges = edge2;
        };

        ClipperLib.Clipper.prototype.SwapPositionsInSEL = function (edge1, edge2) {
          if (edge1.NextInSEL === null && edge1.PrevInSEL === null) return;
          if (edge2.NextInSEL === null && edge2.PrevInSEL === null) return;

          if (edge1.NextInSEL == edge2) {
            var next = edge2.NextInSEL;
            if (next !== null) next.PrevInSEL = edge1;
            var prev = edge1.PrevInSEL;
            if (prev !== null) prev.NextInSEL = edge2;
            edge2.PrevInSEL = prev;
            edge2.NextInSEL = edge1;
            edge1.PrevInSEL = edge2;
            edge1.NextInSEL = next;
          } else if (edge2.NextInSEL == edge1) {
            var next = edge1.NextInSEL;
            if (next !== null) next.PrevInSEL = edge2;
            var prev = edge2.PrevInSEL;
            if (prev !== null) prev.NextInSEL = edge1;
            edge1.PrevInSEL = prev;
            edge1.NextInSEL = edge2;
            edge2.PrevInSEL = edge1;
            edge2.NextInSEL = next;
          } else {
            var next = edge1.NextInSEL;
            var prev = edge1.PrevInSEL;
            edge1.NextInSEL = edge2.NextInSEL;
            if (edge1.NextInSEL !== null) edge1.NextInSEL.PrevInSEL = edge1;
            edge1.PrevInSEL = edge2.PrevInSEL;
            if (edge1.PrevInSEL !== null) edge1.PrevInSEL.NextInSEL = edge1;
            edge2.NextInSEL = next;
            if (edge2.NextInSEL !== null) edge2.NextInSEL.PrevInSEL = edge2;
            edge2.PrevInSEL = prev;
            if (edge2.PrevInSEL !== null) edge2.PrevInSEL.NextInSEL = edge2;
          }

          if (edge1.PrevInSEL === null) this.m_SortedEdges = edge1;else if (edge2.PrevInSEL === null) this.m_SortedEdges = edge2;
        };

        ClipperLib.Clipper.prototype.AddLocalMaxPoly = function (e1, e2, pt) {
          this.AddOutPt(e1, pt);
          if (e2.WindDelta == 0) this.AddOutPt(e2, pt);

          if (e1.OutIdx == e2.OutIdx) {
            e1.OutIdx = -1;
            e2.OutIdx = -1;
          } else if (e1.OutIdx < e2.OutIdx) this.AppendPolygon(e1, e2);else this.AppendPolygon(e2, e1);
        };

        ClipperLib.Clipper.prototype.AddLocalMinPoly = function (e1, e2, pt) {
          var result;
          var e, prevE;

          if (ClipperLib.ClipperBase.IsHorizontal(e2) || e1.Dx > e2.Dx) {
            result = this.AddOutPt(e1, pt);
            e2.OutIdx = e1.OutIdx;
            e1.Side = ClipperLib.EdgeSide.esLeft;
            e2.Side = ClipperLib.EdgeSide.esRight;
            e = e1;
            if (e.PrevInAEL == e2) prevE = e2.PrevInAEL;else prevE = e.PrevInAEL;
          } else {
            result = this.AddOutPt(e2, pt);
            e1.OutIdx = e2.OutIdx;
            e1.Side = ClipperLib.EdgeSide.esRight;
            e2.Side = ClipperLib.EdgeSide.esLeft;
            e = e2;
            if (e.PrevInAEL == e1) prevE = e1.PrevInAEL;else prevE = e.PrevInAEL;
          }

          if (prevE !== null && prevE.OutIdx >= 0 && ClipperLib.Clipper.TopX(prevE, pt.Y) == ClipperLib.Clipper.TopX(e, pt.Y) && ClipperLib.ClipperBase.SlopesEqual(e, prevE, this.m_UseFullRange) && e.WindDelta !== 0 && prevE.WindDelta !== 0) {
            var outPt = this.AddOutPt(prevE, pt);
            this.AddJoin(result, outPt, e.Top);
          }

          return result;
        };

        ClipperLib.Clipper.prototype.CreateOutRec = function () {
          var result = new ClipperLib.OutRec();
          result.Idx = -1;
          result.IsHole = false;
          result.IsOpen = false;
          result.FirstLeft = null;
          result.Pts = null;
          result.BottomPt = null;
          result.PolyNode = null;
          this.m_PolyOuts.push(result);
          result.Idx = this.m_PolyOuts.length - 1;
          return result;
        };

        ClipperLib.Clipper.prototype.AddOutPt = function (e, pt) {
          var ToFront = e.Side == ClipperLib.EdgeSide.esLeft;

          if (e.OutIdx < 0) {
            var outRec = this.CreateOutRec();
            outRec.IsOpen = e.WindDelta === 0;
            var newOp = new ClipperLib.OutPt();
            outRec.Pts = newOp;
            newOp.Idx = outRec.Idx; //newOp.Pt = pt;

            newOp.Pt.X = pt.X;
            newOp.Pt.Y = pt.Y;
            newOp.Next = newOp;
            newOp.Prev = newOp;
            if (!outRec.IsOpen) this.SetHoleState(e, outRec);
            e.OutIdx = outRec.Idx; //nb: do this after SetZ !

            return newOp;
          } else {
            var outRec = this.m_PolyOuts[e.OutIdx]; //OutRec.Pts is the 'Left-most' point & OutRec.Pts.Prev is the 'Right-most'

            var op = outRec.Pts;
            if (ToFront && ClipperLib.IntPoint.op_Equality(pt, op.Pt)) return op;else if (!ToFront && ClipperLib.IntPoint.op_Equality(pt, op.Prev.Pt)) return op.Prev;
            var newOp = new ClipperLib.OutPt();
            newOp.Idx = outRec.Idx; //newOp.Pt = pt;

            newOp.Pt.X = pt.X;
            newOp.Pt.Y = pt.Y;
            newOp.Next = op;
            newOp.Prev = op.Prev;
            newOp.Prev.Next = newOp;
            op.Prev = newOp;
            if (ToFront) outRec.Pts = newOp;
            return newOp;
          }
        };

        ClipperLib.Clipper.prototype.SwapPoints = function (pt1, pt2) {
          var tmp = new ClipperLib.IntPoint(pt1.Value); //pt1.Value = pt2.Value;

          pt1.Value.X = pt2.Value.X;
          pt1.Value.Y = pt2.Value.Y; //pt2.Value = tmp;

          pt2.Value.X = tmp.X;
          pt2.Value.Y = tmp.Y;
        };

        ClipperLib.Clipper.prototype.HorzSegmentsOverlap = function (Pt1a, Pt1b, Pt2a, Pt2b) {
          //precondition: both segments are horizontal
          if (Pt1a.X > Pt2a.X == Pt1a.X < Pt2b.X) return true;else if (Pt1b.X > Pt2a.X == Pt1b.X < Pt2b.X) return true;else if (Pt2a.X > Pt1a.X == Pt2a.X < Pt1b.X) return true;else if (Pt2b.X > Pt1a.X == Pt2b.X < Pt1b.X) return true;else if (Pt1a.X == Pt2a.X && Pt1b.X == Pt2b.X) return true;else if (Pt1a.X == Pt2b.X && Pt1b.X == Pt2a.X) return true;else return false;
        };

        ClipperLib.Clipper.prototype.InsertPolyPtBetween = function (p1, p2, pt) {
          var result = new ClipperLib.OutPt(); //result.Pt = pt;

          result.Pt.X = pt.X;
          result.Pt.Y = pt.Y;

          if (p2 == p1.Next) {
            p1.Next = result;
            p2.Prev = result;
            result.Next = p2;
            result.Prev = p1;
          } else {
            p2.Next = result;
            p1.Prev = result;
            result.Next = p1;
            result.Prev = p2;
          }

          return result;
        };

        ClipperLib.Clipper.prototype.SetHoleState = function (e, outRec) {
          var isHole = false;
          var e2 = e.PrevInAEL;

          while (e2 !== null) {
            if (e2.OutIdx >= 0 && e2.WindDelta != 0) {
              isHole = !isHole;
              if (outRec.FirstLeft === null) outRec.FirstLeft = this.m_PolyOuts[e2.OutIdx];
            }

            e2 = e2.PrevInAEL;
          }

          if (isHole) outRec.IsHole = true;
        };

        ClipperLib.Clipper.prototype.GetDx = function (pt1, pt2) {
          if (pt1.Y == pt2.Y) return ClipperLib.ClipperBase.horizontal;else return (pt2.X - pt1.X) / (pt2.Y - pt1.Y);
        };

        ClipperLib.Clipper.prototype.FirstIsBottomPt = function (btmPt1, btmPt2) {
          var p = btmPt1.Prev;

          while (ClipperLib.IntPoint.op_Equality(p.Pt, btmPt1.Pt) && p != btmPt1) p = p.Prev;

          var dx1p = Math.abs(this.GetDx(btmPt1.Pt, p.Pt));
          p = btmPt1.Next;

          while (ClipperLib.IntPoint.op_Equality(p.Pt, btmPt1.Pt) && p != btmPt1) p = p.Next;

          var dx1n = Math.abs(this.GetDx(btmPt1.Pt, p.Pt));
          p = btmPt2.Prev;

          while (ClipperLib.IntPoint.op_Equality(p.Pt, btmPt2.Pt) && p != btmPt2) p = p.Prev;

          var dx2p = Math.abs(this.GetDx(btmPt2.Pt, p.Pt));
          p = btmPt2.Next;

          while (ClipperLib.IntPoint.op_Equality(p.Pt, btmPt2.Pt) && p != btmPt2) p = p.Next;

          var dx2n = Math.abs(this.GetDx(btmPt2.Pt, p.Pt));
          return dx1p >= dx2p && dx1p >= dx2n || dx1n >= dx2p && dx1n >= dx2n;
        };

        ClipperLib.Clipper.prototype.GetBottomPt = function (pp) {
          var dups = null;
          var p = pp.Next;

          while (p != pp) {
            if (p.Pt.Y > pp.Pt.Y) {
              pp = p;
              dups = null;
            } else if (p.Pt.Y == pp.Pt.Y && p.Pt.X <= pp.Pt.X) {
              if (p.Pt.X < pp.Pt.X) {
                dups = null;
                pp = p;
              } else {
                if (p.Next != pp && p.Prev != pp) dups = p;
              }
            }

            p = p.Next;
          }

          if (dups !== null) {
            //there appears to be at least 2 vertices at bottomPt so ...
            while (dups != p) {
              if (!this.FirstIsBottomPt(p, dups)) pp = dups;
              dups = dups.Next;

              while (ClipperLib.IntPoint.op_Inequality(dups.Pt, pp.Pt)) dups = dups.Next;
            }
          }

          return pp;
        };

        ClipperLib.Clipper.prototype.GetLowermostRec = function (outRec1, outRec2) {
          //work out which polygon fragment has the correct hole state ...
          if (outRec1.BottomPt === null) outRec1.BottomPt = this.GetBottomPt(outRec1.Pts);
          if (outRec2.BottomPt === null) outRec2.BottomPt = this.GetBottomPt(outRec2.Pts);
          var bPt1 = outRec1.BottomPt;
          var bPt2 = outRec2.BottomPt;
          if (bPt1.Pt.Y > bPt2.Pt.Y) return outRec1;else if (bPt1.Pt.Y < bPt2.Pt.Y) return outRec2;else if (bPt1.Pt.X < bPt2.Pt.X) return outRec1;else if (bPt1.Pt.X > bPt2.Pt.X) return outRec2;else if (bPt1.Next == bPt1) return outRec2;else if (bPt2.Next == bPt2) return outRec1;else if (this.FirstIsBottomPt(bPt1, bPt2)) return outRec1;else return outRec2;
        };

        ClipperLib.Clipper.prototype.Param1RightOfParam2 = function (outRec1, outRec2) {
          do {
            outRec1 = outRec1.FirstLeft;
            if (outRec1 == outRec2) return true;
          } while (outRec1 !== null);

          return false;
        };

        ClipperLib.Clipper.prototype.GetOutRec = function (idx) {
          var outrec = this.m_PolyOuts[idx];

          while (outrec != this.m_PolyOuts[outrec.Idx]) outrec = this.m_PolyOuts[outrec.Idx];

          return outrec;
        };

        ClipperLib.Clipper.prototype.AppendPolygon = function (e1, e2) {
          //get the start and ends of both output polygons ...
          var outRec1 = this.m_PolyOuts[e1.OutIdx];
          var outRec2 = this.m_PolyOuts[e2.OutIdx];
          var holeStateRec;
          if (this.Param1RightOfParam2(outRec1, outRec2)) holeStateRec = outRec2;else if (this.Param1RightOfParam2(outRec2, outRec1)) holeStateRec = outRec1;else holeStateRec = this.GetLowermostRec(outRec1, outRec2);
          var p1_lft = outRec1.Pts;
          var p1_rt = p1_lft.Prev;
          var p2_lft = outRec2.Pts;
          var p2_rt = p2_lft.Prev;
          var side; //join e2 poly onto e1 poly and delete pointers to e2 ...

          if (e1.Side == ClipperLib.EdgeSide.esLeft) {
            if (e2.Side == ClipperLib.EdgeSide.esLeft) {
              //z y x a b c
              this.ReversePolyPtLinks(p2_lft);
              p2_lft.Next = p1_lft;
              p1_lft.Prev = p2_lft;
              p1_rt.Next = p2_rt;
              p2_rt.Prev = p1_rt;
              outRec1.Pts = p2_rt;
            } else {
              //x y z a b c
              p2_rt.Next = p1_lft;
              p1_lft.Prev = p2_rt;
              p2_lft.Prev = p1_rt;
              p1_rt.Next = p2_lft;
              outRec1.Pts = p2_lft;
            }

            side = ClipperLib.EdgeSide.esLeft;
          } else {
            if (e2.Side == ClipperLib.EdgeSide.esRight) {
              //a b c z y x
              this.ReversePolyPtLinks(p2_lft);
              p1_rt.Next = p2_rt;
              p2_rt.Prev = p1_rt;
              p2_lft.Next = p1_lft;
              p1_lft.Prev = p2_lft;
            } else {
              //a b c x y z
              p1_rt.Next = p2_lft;
              p2_lft.Prev = p1_rt;
              p1_lft.Prev = p2_rt;
              p2_rt.Next = p1_lft;
            }

            side = ClipperLib.EdgeSide.esRight;
          }

          outRec1.BottomPt = null;

          if (holeStateRec == outRec2) {
            if (outRec2.FirstLeft != outRec1) outRec1.FirstLeft = outRec2.FirstLeft;
            outRec1.IsHole = outRec2.IsHole;
          }

          outRec2.Pts = null;
          outRec2.BottomPt = null;
          outRec2.FirstLeft = outRec1;
          var OKIdx = e1.OutIdx;
          var ObsoleteIdx = e2.OutIdx;
          e1.OutIdx = -1; //nb: safe because we only get here via AddLocalMaxPoly

          e2.OutIdx = -1;
          var e = this.m_ActiveEdges;

          while (e !== null) {
            if (e.OutIdx == ObsoleteIdx) {
              e.OutIdx = OKIdx;
              e.Side = side;
              break;
            }

            e = e.NextInAEL;
          }

          outRec2.Idx = outRec1.Idx;
        };

        ClipperLib.Clipper.prototype.ReversePolyPtLinks = function (pp) {
          if (pp === null) return;
          var pp1;
          var pp2;
          pp1 = pp;

          do {
            pp2 = pp1.Next;
            pp1.Next = pp1.Prev;
            pp1.Prev = pp2;
            pp1 = pp2;
          } while (pp1 != pp);
        };

        ClipperLib.Clipper.SwapSides = function (edge1, edge2) {
          var side = edge1.Side;
          edge1.Side = edge2.Side;
          edge2.Side = side;
        };

        ClipperLib.Clipper.SwapPolyIndexes = function (edge1, edge2) {
          var outIdx = edge1.OutIdx;
          edge1.OutIdx = edge2.OutIdx;
          edge2.OutIdx = outIdx;
        };

        ClipperLib.Clipper.prototype.IntersectEdges = function (e1, e2, pt, protect) {
          //e1 will be to the left of e2 BELOW the intersection. Therefore e1 is before
          //e2 in AEL except when e1 is being inserted at the intersection point ...
          var e1stops = !protect && e1.NextInLML === null && e1.Top.X == pt.X && e1.Top.Y == pt.Y;
          var e2stops = !protect && e2.NextInLML === null && e2.Top.X == pt.X && e2.Top.Y == pt.Y;
          var e1Contributing = e1.OutIdx >= 0;
          var e2Contributing = e2.OutIdx >= 0;
          {
            //if either edge is on an OPEN path ...
            if (e1.WindDelta === 0 || e2.WindDelta === 0) {
              //ignore subject-subject open path intersections UNLESS they
              //are both open paths, AND they are both 'contributing maximas' ...
              if (e1.WindDelta === 0 && e2.WindDelta === 0) {
                if ((e1stops || e2stops) && e1Contributing && e2Contributing) this.AddLocalMaxPoly(e1, e2, pt);
              } //if intersecting a subj line with a subj poly ...
              else if (e1.PolyTyp == e2.PolyTyp && e1.WindDelta != e2.WindDelta && this.m_ClipType == ClipperLib.ClipType.ctUnion) {
                  if (e1.WindDelta === 0) {
                    if (e2Contributing) {
                      this.AddOutPt(e1, pt);
                      if (e1Contributing) e1.OutIdx = -1;
                    }
                  } else {
                    if (e1Contributing) {
                      this.AddOutPt(e2, pt);
                      if (e2Contributing) e2.OutIdx = -1;
                    }
                  }
                } else if (e1.PolyTyp != e2.PolyTyp) {
                  if (e1.WindDelta === 0 && Math.abs(e2.WindCnt) == 1 && (this.m_ClipType != ClipperLib.ClipType.ctUnion || e2.WindCnt2 === 0)) {
                    this.AddOutPt(e1, pt);
                    if (e1Contributing) e1.OutIdx = -1;
                  } else if (e2.WindDelta === 0 && Math.abs(e1.WindCnt) == 1 && (this.m_ClipType != ClipperLib.ClipType.ctUnion || e1.WindCnt2 === 0)) {
                    this.AddOutPt(e2, pt);
                    if (e2Contributing) e2.OutIdx = -1;
                  }
                }

              if (e1stops) if (e1.OutIdx < 0) this.DeleteFromAEL(e1);else ClipperLib.Error("Error intersecting polylines");
              if (e2stops) if (e2.OutIdx < 0) this.DeleteFromAEL(e2);else ClipperLib.Error("Error intersecting polylines");
              return;
            }
          } //update winding counts...
          //assumes that e1 will be to the Right of e2 ABOVE the intersection

          if (e1.PolyTyp == e2.PolyTyp) {
            if (this.IsEvenOddFillType(e1)) {
              var oldE1WindCnt = e1.WindCnt;
              e1.WindCnt = e2.WindCnt;
              e2.WindCnt = oldE1WindCnt;
            } else {
              if (e1.WindCnt + e2.WindDelta === 0) e1.WindCnt = -e1.WindCnt;else e1.WindCnt += e2.WindDelta;
              if (e2.WindCnt - e1.WindDelta === 0) e2.WindCnt = -e2.WindCnt;else e2.WindCnt -= e1.WindDelta;
            }
          } else {
            if (!this.IsEvenOddFillType(e2)) e1.WindCnt2 += e2.WindDelta;else e1.WindCnt2 = e1.WindCnt2 === 0 ? 1 : 0;
            if (!this.IsEvenOddFillType(e1)) e2.WindCnt2 -= e1.WindDelta;else e2.WindCnt2 = e2.WindCnt2 === 0 ? 1 : 0;
          }

          var e1FillType, e2FillType, e1FillType2, e2FillType2;

          if (e1.PolyTyp == ClipperLib.PolyType.ptSubject) {
            e1FillType = this.m_SubjFillType;
            e1FillType2 = this.m_ClipFillType;
          } else {
            e1FillType = this.m_ClipFillType;
            e1FillType2 = this.m_SubjFillType;
          }

          if (e2.PolyTyp == ClipperLib.PolyType.ptSubject) {
            e2FillType = this.m_SubjFillType;
            e2FillType2 = this.m_ClipFillType;
          } else {
            e2FillType = this.m_ClipFillType;
            e2FillType2 = this.m_SubjFillType;
          }

          var e1Wc, e2Wc;

          switch (e1FillType) {
            case ClipperLib.PolyFillType.pftPositive:
              e1Wc = e1.WindCnt;
              break;

            case ClipperLib.PolyFillType.pftNegative:
              e1Wc = -e1.WindCnt;
              break;

            default:
              e1Wc = Math.abs(e1.WindCnt);
              break;
          }

          switch (e2FillType) {
            case ClipperLib.PolyFillType.pftPositive:
              e2Wc = e2.WindCnt;
              break;

            case ClipperLib.PolyFillType.pftNegative:
              e2Wc = -e2.WindCnt;
              break;

            default:
              e2Wc = Math.abs(e2.WindCnt);
              break;
          }

          if (e1Contributing && e2Contributing) {
            if (e1stops || e2stops || e1Wc !== 0 && e1Wc != 1 || e2Wc !== 0 && e2Wc != 1 || e1.PolyTyp != e2.PolyTyp && this.m_ClipType != ClipperLib.ClipType.ctXor) this.AddLocalMaxPoly(e1, e2, pt);else {
              this.AddOutPt(e1, pt);
              this.AddOutPt(e2, pt);
              ClipperLib.Clipper.SwapSides(e1, e2);
              ClipperLib.Clipper.SwapPolyIndexes(e1, e2);
            }
          } else if (e1Contributing) {
            if (e2Wc === 0 || e2Wc == 1) {
              this.AddOutPt(e1, pt);
              ClipperLib.Clipper.SwapSides(e1, e2);
              ClipperLib.Clipper.SwapPolyIndexes(e1, e2);
            }
          } else if (e2Contributing) {
            if (e1Wc === 0 || e1Wc == 1) {
              this.AddOutPt(e2, pt);
              ClipperLib.Clipper.SwapSides(e1, e2);
              ClipperLib.Clipper.SwapPolyIndexes(e1, e2);
            }
          } else if ((e1Wc === 0 || e1Wc == 1) && (e2Wc === 0 || e2Wc == 1) && !e1stops && !e2stops) {
            //neither edge is currently contributing ...
            var e1Wc2, e2Wc2;

            switch (e1FillType2) {
              case ClipperLib.PolyFillType.pftPositive:
                e1Wc2 = e1.WindCnt2;
                break;

              case ClipperLib.PolyFillType.pftNegative:
                e1Wc2 = -e1.WindCnt2;
                break;

              default:
                e1Wc2 = Math.abs(e1.WindCnt2);
                break;
            }

            switch (e2FillType2) {
              case ClipperLib.PolyFillType.pftPositive:
                e2Wc2 = e2.WindCnt2;
                break;

              case ClipperLib.PolyFillType.pftNegative:
                e2Wc2 = -e2.WindCnt2;
                break;

              default:
                e2Wc2 = Math.abs(e2.WindCnt2);
                break;
            }

            if (e1.PolyTyp != e2.PolyTyp) this.AddLocalMinPoly(e1, e2, pt);else if (e1Wc == 1 && e2Wc == 1) switch (this.m_ClipType) {
              case ClipperLib.ClipType.ctIntersection:
                if (e1Wc2 > 0 && e2Wc2 > 0) this.AddLocalMinPoly(e1, e2, pt);
                break;

              case ClipperLib.ClipType.ctUnion:
                if (e1Wc2 <= 0 && e2Wc2 <= 0) this.AddLocalMinPoly(e1, e2, pt);
                break;

              case ClipperLib.ClipType.ctDifference:
                if (e1.PolyTyp == ClipperLib.PolyType.ptClip && e1Wc2 > 0 && e2Wc2 > 0 || e1.PolyTyp == ClipperLib.PolyType.ptSubject && e1Wc2 <= 0 && e2Wc2 <= 0) this.AddLocalMinPoly(e1, e2, pt);
                break;

              case ClipperLib.ClipType.ctXor:
                this.AddLocalMinPoly(e1, e2, pt);
                break;
            } else ClipperLib.Clipper.SwapSides(e1, e2);
          }

          if (e1stops != e2stops && (e1stops && e1.OutIdx >= 0 || e2stops && e2.OutIdx >= 0)) {
            ClipperLib.Clipper.SwapSides(e1, e2);
            ClipperLib.Clipper.SwapPolyIndexes(e1, e2);
          } //finally, delete any non-contributing maxima edges  ...


          if (e1stops) this.DeleteFromAEL(e1);
          if (e2stops) this.DeleteFromAEL(e2);
        };

        ClipperLib.Clipper.prototype.DeleteFromAEL = function (e) {
          var AelPrev = e.PrevInAEL;
          var AelNext = e.NextInAEL;
          if (AelPrev === null && AelNext === null && e != this.m_ActiveEdges) return; //already deleted

          if (AelPrev !== null) AelPrev.NextInAEL = AelNext;else this.m_ActiveEdges = AelNext;
          if (AelNext !== null) AelNext.PrevInAEL = AelPrev;
          e.NextInAEL = null;
          e.PrevInAEL = null;
        };

        ClipperLib.Clipper.prototype.DeleteFromSEL = function (e) {
          var SelPrev = e.PrevInSEL;
          var SelNext = e.NextInSEL;
          if (SelPrev === null && SelNext === null && e != this.m_SortedEdges) return; //already deleted

          if (SelPrev !== null) SelPrev.NextInSEL = SelNext;else this.m_SortedEdges = SelNext;
          if (SelNext !== null) SelNext.PrevInSEL = SelPrev;
          e.NextInSEL = null;
          e.PrevInSEL = null;
        };

        ClipperLib.Clipper.prototype.UpdateEdgeIntoAEL = function (e) {
          if (e.NextInLML === null) ClipperLib.Error("UpdateEdgeIntoAEL: invalid call");
          var AelPrev = e.PrevInAEL;
          var AelNext = e.NextInAEL;
          e.NextInLML.OutIdx = e.OutIdx;
          if (AelPrev !== null) AelPrev.NextInAEL = e.NextInLML;else this.m_ActiveEdges = e.NextInLML;
          if (AelNext !== null) AelNext.PrevInAEL = e.NextInLML;
          e.NextInLML.Side = e.Side;
          e.NextInLML.WindDelta = e.WindDelta;
          e.NextInLML.WindCnt = e.WindCnt;
          e.NextInLML.WindCnt2 = e.WindCnt2;
          e = e.NextInLML; //    e.Curr = e.Bot;

          e.Curr.X = e.Bot.X;
          e.Curr.Y = e.Bot.Y;
          e.PrevInAEL = AelPrev;
          e.NextInAEL = AelNext;
          if (!ClipperLib.ClipperBase.IsHorizontal(e)) this.InsertScanbeam(e.Top.Y);
          return e;
        };

        ClipperLib.Clipper.prototype.ProcessHorizontals = function (isTopOfScanbeam) {
          var horzEdge = this.m_SortedEdges;

          while (horzEdge !== null) {
            this.DeleteFromSEL(horzEdge);
            this.ProcessHorizontal(horzEdge, isTopOfScanbeam);
            horzEdge = this.m_SortedEdges;
          }
        };

        ClipperLib.Clipper.prototype.GetHorzDirection = function (HorzEdge, $var) {
          if (HorzEdge.Bot.X < HorzEdge.Top.X) {
            $var.Left = HorzEdge.Bot.X;
            $var.Right = HorzEdge.Top.X;
            $var.Dir = ClipperLib.Direction.dLeftToRight;
          } else {
            $var.Left = HorzEdge.Top.X;
            $var.Right = HorzEdge.Bot.X;
            $var.Dir = ClipperLib.Direction.dRightToLeft;
          }
        };

        ClipperLib.Clipper.prototype.PrepareHorzJoins = function (horzEdge, isTopOfScanbeam) {
          //get the last Op for this horizontal edge
          //the point may be anywhere along the horizontal ...
          var outPt = this.m_PolyOuts[horzEdge.OutIdx].Pts;
          if (horzEdge.Side != ClipperLib.EdgeSide.esLeft) outPt = outPt.Prev; //First, match up overlapping horizontal edges (eg when one polygon's
          //intermediate horz edge overlaps an intermediate horz edge of another, or
          //when one polygon sits on top of another) ...
          //for (var i = 0, ilen = this.m_GhostJoins.length; i < ilen; ++i) {
          //  var j = this.m_GhostJoins[i];
          //  if (this.HorzSegmentsOverlap(j.OutPt1.Pt, j.OffPt, horzEdge.Bot, horzEdge.Top))
          //    this.AddJoin(j.OutPt1, outPt, j.OffPt);
          //}
          //Also, since horizontal edges at the top of one SB are often removed from
          //the AEL before we process the horizontal edges at the bottom of the next,
          //we need to create 'ghost' Join records of 'contrubuting' horizontals that
          //we can compare with horizontals at the bottom of the next SB.

          if (isTopOfScanbeam) if (ClipperLib.IntPoint.op_Equality(outPt.Pt, horzEdge.Top)) this.AddGhostJoin(outPt, horzEdge.Bot);else this.AddGhostJoin(outPt, horzEdge.Top);
        };

        ClipperLib.Clipper.prototype.ProcessHorizontal = function (horzEdge, isTopOfScanbeam) {
          var $var = {
            Dir: null,
            Left: null,
            Right: null
          };
          this.GetHorzDirection(horzEdge, $var);
          var dir = $var.Dir;
          var horzLeft = $var.Left;
          var horzRight = $var.Right;
          var eLastHorz = horzEdge,
              eMaxPair = null;

          while (eLastHorz.NextInLML !== null && ClipperLib.ClipperBase.IsHorizontal(eLastHorz.NextInLML)) eLastHorz = eLastHorz.NextInLML;

          if (eLastHorz.NextInLML === null) eMaxPair = this.GetMaximaPair(eLastHorz);

          for (;;) {
            var IsLastHorz = horzEdge == eLastHorz;
            var e = this.GetNextInAEL(horzEdge, dir);

            while (e !== null) {
              //Break if we've got to the end of an intermediate horizontal edge ...
              //nb: Smaller Dx's are to the right of larger Dx's ABOVE the horizontal.
              if (e.Curr.X == horzEdge.Top.X && horzEdge.NextInLML !== null && e.Dx < horzEdge.NextInLML.Dx) break;
              var eNext = this.GetNextInAEL(e, dir); //saves eNext for later

              if (dir == ClipperLib.Direction.dLeftToRight && e.Curr.X <= horzRight || dir == ClipperLib.Direction.dRightToLeft && e.Curr.X >= horzLeft) {
                if (horzEdge.OutIdx >= 0 && horzEdge.WindDelta != 0) this.PrepareHorzJoins(horzEdge, isTopOfScanbeam); //so far we're still in range of the horizontal Edge  but make sure
                //we're at the last of consec. horizontals when matching with eMaxPair

                if (e == eMaxPair && IsLastHorz) {
                  if (dir == ClipperLib.Direction.dLeftToRight) this.IntersectEdges(horzEdge, e, e.Top, false);else this.IntersectEdges(e, horzEdge, e.Top, false);
                  if (eMaxPair.OutIdx >= 0) ClipperLib.Error("ProcessHorizontal error");
                  return;
                } else if (dir == ClipperLib.Direction.dLeftToRight) {
                  var Pt = new ClipperLib.IntPoint(e.Curr.X, horzEdge.Curr.Y);
                  this.IntersectEdges(horzEdge, e, Pt, true);
                } else {
                  var Pt = new ClipperLib.IntPoint(e.Curr.X, horzEdge.Curr.Y);
                  this.IntersectEdges(e, horzEdge, Pt, true);
                }

                this.SwapPositionsInAEL(horzEdge, e);
              } else if (dir == ClipperLib.Direction.dLeftToRight && e.Curr.X >= horzRight || dir == ClipperLib.Direction.dRightToLeft && e.Curr.X <= horzLeft) break;

              e = eNext;
            } //end while


            if (horzEdge.OutIdx >= 0 && horzEdge.WindDelta !== 0) this.PrepareHorzJoins(horzEdge, isTopOfScanbeam);

            if (horzEdge.NextInLML !== null && ClipperLib.ClipperBase.IsHorizontal(horzEdge.NextInLML)) {
              horzEdge = this.UpdateEdgeIntoAEL(horzEdge);
              if (horzEdge.OutIdx >= 0) this.AddOutPt(horzEdge, horzEdge.Bot);
              var $var = {
                Dir: dir,
                Left: horzLeft,
                Right: horzRight
              };
              this.GetHorzDirection(horzEdge, $var);
              dir = $var.Dir;
              horzLeft = $var.Left;
              horzRight = $var.Right;
            } else break;
          } //end for (;;)


          if (horzEdge.NextInLML !== null) {
            if (horzEdge.OutIdx >= 0) {
              var op1 = this.AddOutPt(horzEdge, horzEdge.Top);
              horzEdge = this.UpdateEdgeIntoAEL(horzEdge);
              if (horzEdge.WindDelta === 0) return; //nb: HorzEdge is no longer horizontal here

              var ePrev = horzEdge.PrevInAEL;
              var eNext = horzEdge.NextInAEL;

              if (ePrev !== null && ePrev.Curr.X == horzEdge.Bot.X && ePrev.Curr.Y == horzEdge.Bot.Y && ePrev.WindDelta !== 0 && ePrev.OutIdx >= 0 && ePrev.Curr.Y > ePrev.Top.Y && ClipperLib.ClipperBase.SlopesEqual(horzEdge, ePrev, this.m_UseFullRange)) {
                var op2 = this.AddOutPt(ePrev, horzEdge.Bot);
                this.AddJoin(op1, op2, horzEdge.Top);
              } else if (eNext !== null && eNext.Curr.X == horzEdge.Bot.X && eNext.Curr.Y == horzEdge.Bot.Y && eNext.WindDelta !== 0 && eNext.OutIdx >= 0 && eNext.Curr.Y > eNext.Top.Y && ClipperLib.ClipperBase.SlopesEqual(horzEdge, eNext, this.m_UseFullRange)) {
                var op2 = this.AddOutPt(eNext, horzEdge.Bot);
                this.AddJoin(op1, op2, horzEdge.Top);
              }
            } else horzEdge = this.UpdateEdgeIntoAEL(horzEdge);
          } else if (eMaxPair !== null) {
            if (eMaxPair.OutIdx >= 0) {
              if (dir == ClipperLib.Direction.dLeftToRight) this.IntersectEdges(horzEdge, eMaxPair, horzEdge.Top, false);else this.IntersectEdges(eMaxPair, horzEdge, horzEdge.Top, false);
              if (eMaxPair.OutIdx >= 0) ClipperLib.Error("ProcessHorizontal error");
            } else {
              this.DeleteFromAEL(horzEdge);
              this.DeleteFromAEL(eMaxPair);
            }
          } else {
            if (horzEdge.OutIdx >= 0) this.AddOutPt(horzEdge, horzEdge.Top);
            this.DeleteFromAEL(horzEdge);
          }
        };

        ClipperLib.Clipper.prototype.GetNextInAEL = function (e, Direction) {
          return Direction == ClipperLib.Direction.dLeftToRight ? e.NextInAEL : e.PrevInAEL;
        };

        ClipperLib.Clipper.prototype.IsMinima = function (e) {
          return e !== null && e.Prev.NextInLML != e && e.Next.NextInLML != e;
        };

        ClipperLib.Clipper.prototype.IsMaxima = function (e, Y) {
          return e !== null && e.Top.Y == Y && e.NextInLML === null;
        };

        ClipperLib.Clipper.prototype.IsIntermediate = function (e, Y) {
          return e.Top.Y == Y && e.NextInLML !== null;
        };

        ClipperLib.Clipper.prototype.GetMaximaPair = function (e) {
          var result = null;
          if (ClipperLib.IntPoint.op_Equality(e.Next.Top, e.Top) && e.Next.NextInLML === null) result = e.Next;else if (ClipperLib.IntPoint.op_Equality(e.Prev.Top, e.Top) && e.Prev.NextInLML === null) result = e.Prev;
          if (result !== null && (result.OutIdx == -2 || result.NextInAEL == result.PrevInAEL && !ClipperLib.ClipperBase.IsHorizontal(result))) return null;
          return result;
        };

        ClipperLib.Clipper.prototype.ProcessIntersections = function (botY, topY) {
          if (this.m_ActiveEdges == null) return true;

          try {
            this.BuildIntersectList(botY, topY);
            if (this.m_IntersectList.length == 0) return true;
            if (this.m_IntersectList.length == 1 || this.FixupIntersectionOrder()) this.ProcessIntersectList();else return false;
          } catch ($$e2) {
            this.m_SortedEdges = null;
            this.m_IntersectList.length = 0;
            ClipperLib.Error("ProcessIntersections error");
          }

          this.m_SortedEdges = null;
          return true;
        };

        ClipperLib.Clipper.prototype.BuildIntersectList = function (botY, topY) {
          if (this.m_ActiveEdges === null) return; //prepare for sorting ...

          var e = this.m_ActiveEdges; //console.log(JSON.stringify(JSON.decycle( e )));

          this.m_SortedEdges = e;

          while (e !== null) {
            e.PrevInSEL = e.PrevInAEL;
            e.NextInSEL = e.NextInAEL;
            e.Curr.X = ClipperLib.Clipper.TopX(e, topY);
            e = e.NextInAEL;
          } //bubblesort ...


          var isModified = true;

          while (isModified && this.m_SortedEdges !== null) {
            isModified = false;
            e = this.m_SortedEdges;

            while (e.NextInSEL !== null) {
              var eNext = e.NextInSEL;
              var pt = new ClipperLib.IntPoint(); //console.log("e.Curr.X: " + e.Curr.X + " eNext.Curr.X" + eNext.Curr.X);

              if (e.Curr.X > eNext.Curr.X) {
                if (!this.IntersectPoint(e, eNext, pt) && e.Curr.X > eNext.Curr.X + 1) {
                  //console.log("e.Curr.X: "+JSON.stringify(JSON.decycle( e.Curr.X )));
                  //console.log("eNext.Curr.X+1: "+JSON.stringify(JSON.decycle( eNext.Curr.X+1)));
                  ClipperLib.Error("Intersection error");
                }

                if (pt.Y > botY) {
                  pt.Y = botY;
                  if (Math.abs(e.Dx) > Math.abs(eNext.Dx)) pt.X = ClipperLib.Clipper.TopX(eNext, botY);else pt.X = ClipperLib.Clipper.TopX(e, botY);
                }

                var newNode = new ClipperLib.IntersectNode();
                newNode.Edge1 = e;
                newNode.Edge2 = eNext; //newNode.Pt = pt;

                newNode.Pt.X = pt.X;
                newNode.Pt.Y = pt.Y;
                this.m_IntersectList.push(newNode);
                this.SwapPositionsInSEL(e, eNext);
                isModified = true;
              } else e = eNext;
            }

            if (e.PrevInSEL !== null) e.PrevInSEL.NextInSEL = null;else break;
          }

          this.m_SortedEdges = null;
        };

        ClipperLib.Clipper.prototype.EdgesAdjacent = function (inode) {
          return inode.Edge1.NextInSEL == inode.Edge2 || inode.Edge1.PrevInSEL == inode.Edge2;
        };

        ClipperLib.Clipper.IntersectNodeSort = function (node1, node2) {
          //the following typecast is safe because the differences in Pt.Y will
          //be limited to the height of the scanbeam.
          return node2.Pt.Y - node1.Pt.Y;
        };

        ClipperLib.Clipper.prototype.FixupIntersectionOrder = function () {
          //pre-condition: intersections are sorted bottom-most first.
          //Now it's crucial that intersections are made only between adjacent edges,
          //so to ensure this the order of intersections may need adjusting ...
          this.m_IntersectList.sort(this.m_IntersectNodeComparer);
          this.CopyAELToSEL();
          var cnt = this.m_IntersectList.length;

          for (var i = 0; i < cnt; i++) {
            if (!this.EdgesAdjacent(this.m_IntersectList[i])) {
              var j = i + 1;

              while (j < cnt && !this.EdgesAdjacent(this.m_IntersectList[j])) j++;

              if (j == cnt) return false;
              var tmp = this.m_IntersectList[i];
              this.m_IntersectList[i] = this.m_IntersectList[j];
              this.m_IntersectList[j] = tmp;
            }

            this.SwapPositionsInSEL(this.m_IntersectList[i].Edge1, this.m_IntersectList[i].Edge2);
          }

          return true;
        };

        ClipperLib.Clipper.prototype.ProcessIntersectList = function () {
          for (var i = 0, ilen = this.m_IntersectList.length; i < ilen; i++) {
            var iNode = this.m_IntersectList[i];
            this.IntersectEdges(iNode.Edge1, iNode.Edge2, iNode.Pt, true);
            this.SwapPositionsInAEL(iNode.Edge1, iNode.Edge2);
          }

          this.m_IntersectList.length = 0;
        };
        /*
        --------------------------------
        Round speedtest: http://jsperf.com/fastest-round
        --------------------------------
        */


        var R1 = function R1(a) {
          return a < 0 ? Math.ceil(a - 0.5) : Math.round(a);
        };

        var R2 = function R2(a) {
          return a < 0 ? Math.ceil(a - 0.5) : Math.floor(a + 0.5);
        };

        var R3 = function R3(a) {
          return a < 0 ? -Math.round(Math.abs(a)) : Math.round(a);
        };

        var R4 = function R4(a) {
          if (a < 0) {
            a -= 0.5;
            return a < -2147483648 ? Math.ceil(a) : a | 0;
          } else {
            a += 0.5;
            return a > 2147483647 ? Math.floor(a) : a | 0;
          }
        };

        if (browser.msie) ClipperLib.Clipper.Round = R1;else if (browser.chromium) ClipperLib.Clipper.Round = R3;else if (browser.safari) ClipperLib.Clipper.Round = R4;else ClipperLib.Clipper.Round = R2; // eg. browser.chrome || browser.firefox || browser.opera

        ClipperLib.Clipper.TopX = function (edge, currentY) {
          //if (edge.Bot == edge.Curr) alert ("edge.Bot = edge.Curr");
          //if (edge.Bot == edge.Top) alert ("edge.Bot = edge.Top");
          if (currentY == edge.Top.Y) return edge.Top.X;
          return edge.Bot.X + ClipperLib.Clipper.Round(edge.Dx * (currentY - edge.Bot.Y));
        };

        ClipperLib.Clipper.prototype.IntersectPoint = function (edge1, edge2, ip) {
          ip.X = 0;
          ip.Y = 0;
          var b1, b2; //nb: with very large coordinate values, it's possible for SlopesEqual() to 
          //return false but for the edge.Dx value be equal due to double precision rounding.

          if (ClipperLib.ClipperBase.SlopesEqual(edge1, edge2, this.m_UseFullRange) || edge1.Dx == edge2.Dx) {
            if (edge2.Bot.Y > edge1.Bot.Y) {
              ip.X = edge2.Bot.X;
              ip.Y = edge2.Bot.Y;
            } else {
              ip.X = edge1.Bot.X;
              ip.Y = edge1.Bot.Y;
            }

            return false;
          } else if (edge1.Delta.X === 0) {
            ip.X = edge1.Bot.X;

            if (ClipperLib.ClipperBase.IsHorizontal(edge2)) {
              ip.Y = edge2.Bot.Y;
            } else {
              b2 = edge2.Bot.Y - edge2.Bot.X / edge2.Dx;
              ip.Y = ClipperLib.Clipper.Round(ip.X / edge2.Dx + b2);
            }
          } else if (edge2.Delta.X === 0) {
            ip.X = edge2.Bot.X;

            if (ClipperLib.ClipperBase.IsHorizontal(edge1)) {
              ip.Y = edge1.Bot.Y;
            } else {
              b1 = edge1.Bot.Y - edge1.Bot.X / edge1.Dx;
              ip.Y = ClipperLib.Clipper.Round(ip.X / edge1.Dx + b1);
            }
          } else {
            b1 = edge1.Bot.X - edge1.Bot.Y * edge1.Dx;
            b2 = edge2.Bot.X - edge2.Bot.Y * edge2.Dx;
            var q = (b2 - b1) / (edge1.Dx - edge2.Dx);
            ip.Y = ClipperLib.Clipper.Round(q);
            if (Math.abs(edge1.Dx) < Math.abs(edge2.Dx)) ip.X = ClipperLib.Clipper.Round(edge1.Dx * q + b1);else ip.X = ClipperLib.Clipper.Round(edge2.Dx * q + b2);
          }

          if (ip.Y < edge1.Top.Y || ip.Y < edge2.Top.Y) {
            if (edge1.Top.Y > edge2.Top.Y) {
              ip.Y = edge1.Top.Y;
              ip.X = ClipperLib.Clipper.TopX(edge2, edge1.Top.Y);
              return ip.X < edge1.Top.X;
            } else ip.Y = edge2.Top.Y;

            if (Math.abs(edge1.Dx) < Math.abs(edge2.Dx)) ip.X = ClipperLib.Clipper.TopX(edge1, ip.Y);else ip.X = ClipperLib.Clipper.TopX(edge2, ip.Y);
          }

          return true;
        };

        ClipperLib.Clipper.prototype.ProcessEdgesAtTopOfScanbeam = function (topY) {
          var e = this.m_ActiveEdges;

          while (e !== null) {
            //1. process maxima, treating them as if they're 'bent' horizontal edges,
            //   but exclude maxima with horizontal edges. nb: e can't be a horizontal.
            var IsMaximaEdge = this.IsMaxima(e, topY);

            if (IsMaximaEdge) {
              var eMaxPair = this.GetMaximaPair(e);
              IsMaximaEdge = eMaxPair === null || !ClipperLib.ClipperBase.IsHorizontal(eMaxPair);
            }

            if (IsMaximaEdge) {
              var ePrev = e.PrevInAEL;
              this.DoMaxima(e);
              if (ePrev === null) e = this.m_ActiveEdges;else e = ePrev.NextInAEL;
            } else {
              //2. promote horizontal edges, otherwise update Curr.X and Curr.Y ...
              if (this.IsIntermediate(e, topY) && ClipperLib.ClipperBase.IsHorizontal(e.NextInLML)) {
                e = this.UpdateEdgeIntoAEL(e);
                if (e.OutIdx >= 0) this.AddOutPt(e, e.Bot);
                this.AddEdgeToSEL(e);
              } else {
                e.Curr.X = ClipperLib.Clipper.TopX(e, topY);
                e.Curr.Y = topY;
              }

              if (this.StrictlySimple) {
                var ePrev = e.PrevInAEL;

                if (e.OutIdx >= 0 && e.WindDelta !== 0 && ePrev !== null && ePrev.OutIdx >= 0 && ePrev.Curr.X == e.Curr.X && ePrev.WindDelta !== 0) {
                  var op = this.AddOutPt(ePrev, e.Curr);
                  var op2 = this.AddOutPt(e, e.Curr);
                  this.AddJoin(op, op2, e.Curr); //StrictlySimple (type-3) join
                }
              }

              e = e.NextInAEL;
            }
          } //3. Process horizontals at the Top of the scanbeam ...


          this.ProcessHorizontals(true); //4. Promote intermediate vertices ...

          e = this.m_ActiveEdges;

          while (e !== null) {
            if (this.IsIntermediate(e, topY)) {
              var op = null;
              if (e.OutIdx >= 0) op = this.AddOutPt(e, e.Top);
              e = this.UpdateEdgeIntoAEL(e); //if output polygons share an edge, they'll need joining later ...

              var ePrev = e.PrevInAEL;
              var eNext = e.NextInAEL;

              if (ePrev !== null && ePrev.Curr.X == e.Bot.X && ePrev.Curr.Y == e.Bot.Y && op !== null && ePrev.OutIdx >= 0 && ePrev.Curr.Y > ePrev.Top.Y && ClipperLib.ClipperBase.SlopesEqual(e, ePrev, this.m_UseFullRange) && e.WindDelta !== 0 && ePrev.WindDelta !== 0) {
                var op2 = this.AddOutPt(ePrev, e.Bot);
                this.AddJoin(op, op2, e.Top);
              } else if (eNext !== null && eNext.Curr.X == e.Bot.X && eNext.Curr.Y == e.Bot.Y && op !== null && eNext.OutIdx >= 0 && eNext.Curr.Y > eNext.Top.Y && ClipperLib.ClipperBase.SlopesEqual(e, eNext, this.m_UseFullRange) && e.WindDelta !== 0 && eNext.WindDelta !== 0) {
                var op2 = this.AddOutPt(eNext, e.Bot);
                this.AddJoin(op, op2, e.Top);
              }
            }

            e = e.NextInAEL;
          }
        };

        ClipperLib.Clipper.prototype.DoMaxima = function (e) {
          var eMaxPair = this.GetMaximaPair(e);

          if (eMaxPair === null) {
            if (e.OutIdx >= 0) this.AddOutPt(e, e.Top);
            this.DeleteFromAEL(e);
            return;
          }

          var eNext = e.NextInAEL;

          while (eNext !== null && eNext != eMaxPair) {
            this.IntersectEdges(e, eNext, e.Top, true);
            this.SwapPositionsInAEL(e, eNext);
            eNext = e.NextInAEL;
          }

          if (e.OutIdx == -1 && eMaxPair.OutIdx == -1) {
            this.DeleteFromAEL(e);
            this.DeleteFromAEL(eMaxPair);
          } else if (e.OutIdx >= 0 && eMaxPair.OutIdx >= 0) {
            this.IntersectEdges(e, eMaxPair, e.Top, false);
          } else if (e.WindDelta === 0) {
            if (e.OutIdx >= 0) {
              this.AddOutPt(e, e.Top);
              e.OutIdx = -1;
            }

            this.DeleteFromAEL(e);

            if (eMaxPair.OutIdx >= 0) {
              this.AddOutPt(eMaxPair, e.Top);
              eMaxPair.OutIdx = -1;
            }

            this.DeleteFromAEL(eMaxPair);
          } else ClipperLib.Error("DoMaxima error");
        };

        ClipperLib.Clipper.ReversePaths = function (polys) {
          for (var i = 0, len = polys.length; i < len; i++) polys[i].reverse();
        };

        ClipperLib.Clipper.Orientation = function (poly) {
          return ClipperLib.Clipper.Area(poly) >= 0;
        };

        ClipperLib.Clipper.prototype.PointCount = function (pts) {
          if (pts === null) return 0;
          var result = 0;
          var p = pts;

          do {
            result++;
            p = p.Next;
          } while (p != pts);

          return result;
        };

        ClipperLib.Clipper.prototype.BuildResult = function (polyg) {
          ClipperLib.Clear(polyg);

          for (var i = 0, ilen = this.m_PolyOuts.length; i < ilen; i++) {
            var outRec = this.m_PolyOuts[i];
            if (outRec.Pts === null) continue;
            var p = outRec.Pts.Prev;
            var cnt = this.PointCount(p);
            if (cnt < 2) continue;
            var pg = new Array(cnt);

            for (var j = 0; j < cnt; j++) {
              pg[j] = p.Pt;
              p = p.Prev;
            }

            polyg.push(pg);
          }
        };

        ClipperLib.Clipper.prototype.BuildResult2 = function (polytree) {
          polytree.Clear(); //add each output polygon/contour to polytree ...
          //polytree.m_AllPolys.set_Capacity(this.m_PolyOuts.length);

          for (var i = 0, ilen = this.m_PolyOuts.length; i < ilen; i++) {
            var outRec = this.m_PolyOuts[i];
            var cnt = this.PointCount(outRec.Pts);
            if (outRec.IsOpen && cnt < 2 || !outRec.IsOpen && cnt < 3) continue;
            this.FixHoleLinkage(outRec);
            var pn = new ClipperLib.PolyNode();
            polytree.m_AllPolys.push(pn);
            outRec.PolyNode = pn;
            pn.m_polygon.length = cnt;
            var op = outRec.Pts.Prev;

            for (var j = 0; j < cnt; j++) {
              pn.m_polygon[j] = op.Pt;
              op = op.Prev;
            }
          } //fixup PolyNode links etc ...
          //polytree.m_Childs.set_Capacity(this.m_PolyOuts.length);


          for (var i = 0, ilen = this.m_PolyOuts.length; i < ilen; i++) {
            var outRec = this.m_PolyOuts[i];
            if (outRec.PolyNode === null) continue;else if (outRec.IsOpen) {
              outRec.PolyNode.IsOpen = true;
              polytree.AddChild(outRec.PolyNode);
            } else if (outRec.FirstLeft !== null && outRec.FirstLeft.PolyNode != null) outRec.FirstLeft.PolyNode.AddChild(outRec.PolyNode);else polytree.AddChild(outRec.PolyNode);
          }
        };

        ClipperLib.Clipper.prototype.FixupOutPolygon = function (outRec) {
          //FixupOutPolygon() - removes duplicate points and simplifies consecutive
          //parallel edges by removing the middle vertex.
          var lastOK = null;
          outRec.BottomPt = null;
          var pp = outRec.Pts;

          for (;;) {
            if (pp.Prev == pp || pp.Prev == pp.Next) {
              this.DisposeOutPts(pp);
              outRec.Pts = null;
              return;
            } //test for duplicate points and collinear edges ...


            if (ClipperLib.IntPoint.op_Equality(pp.Pt, pp.Next.Pt) || ClipperLib.IntPoint.op_Equality(pp.Pt, pp.Prev.Pt) || ClipperLib.ClipperBase.SlopesEqual(pp.Prev.Pt, pp.Pt, pp.Next.Pt, this.m_UseFullRange) && (!this.PreserveCollinear || !this.Pt2IsBetweenPt1AndPt3(pp.Prev.Pt, pp.Pt, pp.Next.Pt))) {
              lastOK = null;
              pp.Prev.Next = pp.Next;
              pp.Next.Prev = pp.Prev;
              pp = pp.Prev;
            } else if (pp == lastOK) break;else {
              if (lastOK === null) lastOK = pp;
              pp = pp.Next;
            }
          }

          outRec.Pts = pp;
        };

        ClipperLib.Clipper.prototype.DupOutPt = function (outPt, InsertAfter) {
          var result = new ClipperLib.OutPt(); //result.Pt = outPt.Pt;

          result.Pt.X = outPt.Pt.X;
          result.Pt.Y = outPt.Pt.Y;
          result.Idx = outPt.Idx;

          if (InsertAfter) {
            result.Next = outPt.Next;
            result.Prev = outPt;
            outPt.Next.Prev = result;
            outPt.Next = result;
          } else {
            result.Prev = outPt.Prev;
            result.Next = outPt;
            outPt.Prev.Next = result;
            outPt.Prev = result;
          }

          return result;
        };

        ClipperLib.Clipper.prototype.GetOverlap = function (a1, a2, b1, b2, $val) {
          if (a1 < a2) {
            if (b1 < b2) {
              $val.Left = Math.max(a1, b1);
              $val.Right = Math.min(a2, b2);
            } else {
              $val.Left = Math.max(a1, b2);
              $val.Right = Math.min(a2, b1);
            }
          } else {
            if (b1 < b2) {
              $val.Left = Math.max(a2, b1);
              $val.Right = Math.min(a1, b2);
            } else {
              $val.Left = Math.max(a2, b2);
              $val.Right = Math.min(a1, b1);
            }
          }

          return $val.Left < $val.Right;
        };

        ClipperLib.Clipper.prototype.JoinHorz = function (op1, op1b, op2, op2b, Pt, DiscardLeft) {
          var Dir1 = op1.Pt.X > op1b.Pt.X ? ClipperLib.Direction.dRightToLeft : ClipperLib.Direction.dLeftToRight;
          var Dir2 = op2.Pt.X > op2b.Pt.X ? ClipperLib.Direction.dRightToLeft : ClipperLib.Direction.dLeftToRight;
          if (Dir1 == Dir2) return false; //When DiscardLeft, we want Op1b to be on the Left of Op1, otherwise we
          //want Op1b to be on the Right. (And likewise with Op2 and Op2b.)
          //So, to facilitate this while inserting Op1b and Op2b ...
          //when DiscardLeft, make sure we're AT or RIGHT of Pt before adding Op1b,
          //otherwise make sure we're AT or LEFT of Pt. (Likewise with Op2b.)

          if (Dir1 == ClipperLib.Direction.dLeftToRight) {
            while (op1.Next.Pt.X <= Pt.X && op1.Next.Pt.X >= op1.Pt.X && op1.Next.Pt.Y == Pt.Y) op1 = op1.Next;

            if (DiscardLeft && op1.Pt.X != Pt.X) op1 = op1.Next;
            op1b = this.DupOutPt(op1, !DiscardLeft);

            if (ClipperLib.IntPoint.op_Inequality(op1b.Pt, Pt)) {
              op1 = op1b; //op1.Pt = Pt;

              op1.Pt.X = Pt.X;
              op1.Pt.Y = Pt.Y;
              op1b = this.DupOutPt(op1, !DiscardLeft);
            }
          } else {
            while (op1.Next.Pt.X >= Pt.X && op1.Next.Pt.X <= op1.Pt.X && op1.Next.Pt.Y == Pt.Y) op1 = op1.Next;

            if (!DiscardLeft && op1.Pt.X != Pt.X) op1 = op1.Next;
            op1b = this.DupOutPt(op1, DiscardLeft);

            if (ClipperLib.IntPoint.op_Inequality(op1b.Pt, Pt)) {
              op1 = op1b; //op1.Pt = Pt;

              op1.Pt.X = Pt.X;
              op1.Pt.Y = Pt.Y;
              op1b = this.DupOutPt(op1, DiscardLeft);
            }
          }

          if (Dir2 == ClipperLib.Direction.dLeftToRight) {
            while (op2.Next.Pt.X <= Pt.X && op2.Next.Pt.X >= op2.Pt.X && op2.Next.Pt.Y == Pt.Y) op2 = op2.Next;

            if (DiscardLeft && op2.Pt.X != Pt.X) op2 = op2.Next;
            op2b = this.DupOutPt(op2, !DiscardLeft);

            if (ClipperLib.IntPoint.op_Inequality(op2b.Pt, Pt)) {
              op2 = op2b; //op2.Pt = Pt;

              op2.Pt.X = Pt.X;
              op2.Pt.Y = Pt.Y;
              op2b = this.DupOutPt(op2, !DiscardLeft);
            }
          } else {
            while (op2.Next.Pt.X >= Pt.X && op2.Next.Pt.X <= op2.Pt.X && op2.Next.Pt.Y == Pt.Y) op2 = op2.Next;

            if (!DiscardLeft && op2.Pt.X != Pt.X) op2 = op2.Next;
            op2b = this.DupOutPt(op2, DiscardLeft);

            if (ClipperLib.IntPoint.op_Inequality(op2b.Pt, Pt)) {
              op2 = op2b; //op2.Pt = Pt;

              op2.Pt.X = Pt.X;
              op2.Pt.Y = Pt.Y;
              op2b = this.DupOutPt(op2, DiscardLeft);
            }
          }

          if (Dir1 == ClipperLib.Direction.dLeftToRight == DiscardLeft) {
            op1.Prev = op2;
            op2.Next = op1;
            op1b.Next = op2b;
            op2b.Prev = op1b;
          } else {
            op1.Next = op2;
            op2.Prev = op1;
            op1b.Prev = op2b;
            op2b.Next = op1b;
          }

          return true;
        };

        ClipperLib.Clipper.prototype.JoinPoints = function (j, outRec1, outRec2) {
          var op1 = j.OutPt1,
              op1b = new ClipperLib.OutPt();
          var op2 = j.OutPt2,
              op2b = new ClipperLib.OutPt(); //There are 3 kinds of joins for output polygons ...
          //1. Horizontal joins where Join.OutPt1 & Join.OutPt2 are a vertices anywhere
          //along (horizontal) collinear edges (& Join.OffPt is on the same horizontal).
          //2. Non-horizontal joins where Join.OutPt1 & Join.OutPt2 are at the same
          //location at the Bottom of the overlapping segment (& Join.OffPt is above).
          //3. StrictlySimple joins where edges touch but are not collinear and where
          //Join.OutPt1, Join.OutPt2 & Join.OffPt all share the same point.

          var isHorizontal = j.OutPt1.Pt.Y == j.OffPt.Y;

          if (isHorizontal && ClipperLib.IntPoint.op_Equality(j.OffPt, j.OutPt1.Pt) && ClipperLib.IntPoint.op_Equality(j.OffPt, j.OutPt2.Pt)) {
            //Strictly Simple join ...
            op1b = j.OutPt1.Next;

            while (op1b != op1 && ClipperLib.IntPoint.op_Equality(op1b.Pt, j.OffPt)) op1b = op1b.Next;

            var reverse1 = op1b.Pt.Y > j.OffPt.Y;
            op2b = j.OutPt2.Next;

            while (op2b != op2 && ClipperLib.IntPoint.op_Equality(op2b.Pt, j.OffPt)) op2b = op2b.Next;

            var reverse2 = op2b.Pt.Y > j.OffPt.Y;
            if (reverse1 == reverse2) return false;

            if (reverse1) {
              op1b = this.DupOutPt(op1, false);
              op2b = this.DupOutPt(op2, true);
              op1.Prev = op2;
              op2.Next = op1;
              op1b.Next = op2b;
              op2b.Prev = op1b;
              j.OutPt1 = op1;
              j.OutPt2 = op1b;
              return true;
            } else {
              op1b = this.DupOutPt(op1, true);
              op2b = this.DupOutPt(op2, false);
              op1.Next = op2;
              op2.Prev = op1;
              op1b.Prev = op2b;
              op2b.Next = op1b;
              j.OutPt1 = op1;
              j.OutPt2 = op1b;
              return true;
            }
          } else if (isHorizontal) {
            //treat horizontal joins differently to non-horizontal joins since with
            //them we're not yet sure where the overlapping is. OutPt1.Pt & OutPt2.Pt
            //may be anywhere along the horizontal edge.
            op1b = op1;

            while (op1.Prev.Pt.Y == op1.Pt.Y && op1.Prev != op1b && op1.Prev != op2) op1 = op1.Prev;

            while (op1b.Next.Pt.Y == op1b.Pt.Y && op1b.Next != op1 && op1b.Next != op2) op1b = op1b.Next;

            if (op1b.Next == op1 || op1b.Next == op2) return false; //a flat 'polygon'

            op2b = op2;

            while (op2.Prev.Pt.Y == op2.Pt.Y && op2.Prev != op2b && op2.Prev != op1b) op2 = op2.Prev;

            while (op2b.Next.Pt.Y == op2b.Pt.Y && op2b.Next != op2 && op2b.Next != op1) op2b = op2b.Next;

            if (op2b.Next == op2 || op2b.Next == op1) return false; //a flat 'polygon'
            //Op1 -. Op1b & Op2 -. Op2b are the extremites of the horizontal edges

            var $val = {
              Left: null,
              Right: null
            };
            if (!this.GetOverlap(op1.Pt.X, op1b.Pt.X, op2.Pt.X, op2b.Pt.X, $val)) return false;
            var Left = $val.Left;
            var Right = $val.Right; //DiscardLeftSide: when overlapping edges are joined, a spike will created
            //which needs to be cleaned up. However, we don't want Op1 or Op2 caught up
            //on the discard Side as either may still be needed for other joins ...

            var Pt = new ClipperLib.IntPoint();
            var DiscardLeftSide;

            if (op1.Pt.X >= Left && op1.Pt.X <= Right) {
              //Pt = op1.Pt;
              Pt.X = op1.Pt.X;
              Pt.Y = op1.Pt.Y;
              DiscardLeftSide = op1.Pt.X > op1b.Pt.X;
            } else if (op2.Pt.X >= Left && op2.Pt.X <= Right) {
              //Pt = op2.Pt;
              Pt.X = op2.Pt.X;
              Pt.Y = op2.Pt.Y;
              DiscardLeftSide = op2.Pt.X > op2b.Pt.X;
            } else if (op1b.Pt.X >= Left && op1b.Pt.X <= Right) {
              //Pt = op1b.Pt;
              Pt.X = op1b.Pt.X;
              Pt.Y = op1b.Pt.Y;
              DiscardLeftSide = op1b.Pt.X > op1.Pt.X;
            } else {
              //Pt = op2b.Pt;
              Pt.X = op2b.Pt.X;
              Pt.Y = op2b.Pt.Y;
              DiscardLeftSide = op2b.Pt.X > op2.Pt.X;
            }

            j.OutPt1 = op1;
            j.OutPt2 = op2;
            return this.JoinHorz(op1, op1b, op2, op2b, Pt, DiscardLeftSide);
          } else {
            //nb: For non-horizontal joins ...
            //    1. Jr.OutPt1.Pt.Y == Jr.OutPt2.Pt.Y
            //    2. Jr.OutPt1.Pt > Jr.OffPt.Y
            //make sure the polygons are correctly oriented ...
            op1b = op1.Next;

            while (ClipperLib.IntPoint.op_Equality(op1b.Pt, op1.Pt) && op1b != op1) op1b = op1b.Next;

            var Reverse1 = op1b.Pt.Y > op1.Pt.Y || !ClipperLib.ClipperBase.SlopesEqual(op1.Pt, op1b.Pt, j.OffPt, this.m_UseFullRange);

            if (Reverse1) {
              op1b = op1.Prev;

              while (ClipperLib.IntPoint.op_Equality(op1b.Pt, op1.Pt) && op1b != op1) op1b = op1b.Prev;

              if (op1b.Pt.Y > op1.Pt.Y || !ClipperLib.ClipperBase.SlopesEqual(op1.Pt, op1b.Pt, j.OffPt, this.m_UseFullRange)) return false;
            }

            op2b = op2.Next;

            while (ClipperLib.IntPoint.op_Equality(op2b.Pt, op2.Pt) && op2b != op2) op2b = op2b.Next;

            var Reverse2 = op2b.Pt.Y > op2.Pt.Y || !ClipperLib.ClipperBase.SlopesEqual(op2.Pt, op2b.Pt, j.OffPt, this.m_UseFullRange);

            if (Reverse2) {
              op2b = op2.Prev;

              while (ClipperLib.IntPoint.op_Equality(op2b.Pt, op2.Pt) && op2b != op2) op2b = op2b.Prev;

              if (op2b.Pt.Y > op2.Pt.Y || !ClipperLib.ClipperBase.SlopesEqual(op2.Pt, op2b.Pt, j.OffPt, this.m_UseFullRange)) return false;
            }

            if (op1b == op1 || op2b == op2 || op1b == op2b || outRec1 == outRec2 && Reverse1 == Reverse2) return false;

            if (Reverse1) {
              op1b = this.DupOutPt(op1, false);
              op2b = this.DupOutPt(op2, true);
              op1.Prev = op2;
              op2.Next = op1;
              op1b.Next = op2b;
              op2b.Prev = op1b;
              j.OutPt1 = op1;
              j.OutPt2 = op1b;
              return true;
            } else {
              op1b = this.DupOutPt(op1, true);
              op2b = this.DupOutPt(op2, false);
              op1.Next = op2;
              op2.Prev = op1;
              op1b.Prev = op2b;
              op2b.Next = op1b;
              j.OutPt1 = op1;
              j.OutPt2 = op1b;
              return true;
            }
          }
        };

        ClipperLib.Clipper.GetBounds = function (paths) {
          var i = 0,
              cnt = paths.length;

          while (i < cnt && paths[i].length == 0) i++;

          if (i == cnt) return new ClipperLib.IntRect(0, 0, 0, 0);
          var result = new ClipperLib.IntRect();
          result.left = paths[i][0].X;
          result.right = result.left;
          result.top = paths[i][0].Y;
          result.bottom = result.top;

          for (; i < cnt; i++) for (var j = 0, jlen = paths[i].length; j < jlen; j++) {
            if (paths[i][j].X < result.left) result.left = paths[i][j].X;else if (paths[i][j].X > result.right) result.right = paths[i][j].X;
            if (paths[i][j].Y < result.top) result.top = paths[i][j].Y;else if (paths[i][j].Y > result.bottom) result.bottom = paths[i][j].Y;
          }

          return result;
        };

        ClipperLib.Clipper.prototype.GetBounds2 = function (ops) {
          var opStart = ops;
          var result = new ClipperLib.IntRect();
          result.left = ops.Pt.X;
          result.right = ops.Pt.X;
          result.top = ops.Pt.Y;
          result.bottom = ops.Pt.Y;
          ops = ops.Next;

          while (ops != opStart) {
            if (ops.Pt.X < result.left) result.left = ops.Pt.X;
            if (ops.Pt.X > result.right) result.right = ops.Pt.X;
            if (ops.Pt.Y < result.top) result.top = ops.Pt.Y;
            if (ops.Pt.Y > result.bottom) result.bottom = ops.Pt.Y;
            ops = ops.Next;
          }

          return result;
        };

        ClipperLib.Clipper.PointInPolygon = function (pt, path) {
          //returns 0 if false, +1 if true, -1 if pt ON polygon boundary
          //http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.88.5498&rep=rep1&type=pdf
          var result = 0,
              cnt = path.length;
          if (cnt < 3) return 0;
          var ip = path[0];

          for (var i = 1; i <= cnt; ++i) {
            var ipNext = i == cnt ? path[0] : path[i];

            if (ipNext.Y == pt.Y) {
              if (ipNext.X == pt.X || ip.Y == pt.Y && ipNext.X > pt.X == ip.X < pt.X) return -1;
            }

            if (ip.Y < pt.Y != ipNext.Y < pt.Y) {
              if (ip.X >= pt.X) {
                if (ipNext.X > pt.X) result = 1 - result;else {
                  var d = (ip.X - pt.X) * (ipNext.Y - pt.Y) - (ipNext.X - pt.X) * (ip.Y - pt.Y);
                  if (d == 0) return -1;else if (d > 0 == ipNext.Y > ip.Y) result = 1 - result;
                }
              } else {
                if (ipNext.X > pt.X) {
                  var d = (ip.X - pt.X) * (ipNext.Y - pt.Y) - (ipNext.X - pt.X) * (ip.Y - pt.Y);
                  if (d == 0) return -1;else if (d > 0 == ipNext.Y > ip.Y) result = 1 - result;
                }
              }
            }

            ip = ipNext;
          }

          return result;
        };

        ClipperLib.Clipper.prototype.PointInPolygon = function (pt, op) {
          //returns 0 if false, +1 if true, -1 if pt ON polygon boundary
          //http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.88.5498&rep=rep1&type=pdf
          var result = 0;
          var startOp = op;

          for (;;) {
            var poly0x = op.Pt.X,
                poly0y = op.Pt.Y;
            var poly1x = op.Next.Pt.X,
                poly1y = op.Next.Pt.Y;

            if (poly1y == pt.Y) {
              if (poly1x == pt.X || poly0y == pt.Y && poly1x > pt.X == poly0x < pt.X) return -1;
            }

            if (poly0y < pt.Y != poly1y < pt.Y) {
              if (poly0x >= pt.X) {
                if (poly1x > pt.X) result = 1 - result;else {
                  var d = (poly0x - pt.X) * (poly1y - pt.Y) - (poly1x - pt.X) * (poly0y - pt.Y);
                  if (d == 0) return -1;
                  if (d > 0 == poly1y > poly0y) result = 1 - result;
                }
              } else {
                if (poly1x > pt.X) {
                  var d = (poly0x - pt.X) * (poly1y - pt.Y) - (poly1x - pt.X) * (poly0y - pt.Y);
                  if (d == 0) return -1;
                  if (d > 0 == poly1y > poly0y) result = 1 - result;
                }
              }
            }

            op = op.Next;
            if (startOp == op) break;
          }

          return result;
        };

        ClipperLib.Clipper.prototype.Poly2ContainsPoly1 = function (outPt1, outPt2) {
          var op = outPt1;

          do {
            var res = this.PointInPolygon(op.Pt, outPt2);
            if (res >= 0) return res != 0;
            op = op.Next;
          } while (op != outPt1);

          return true;
        };

        ClipperLib.Clipper.prototype.FixupFirstLefts1 = function (OldOutRec, NewOutRec) {
          for (var i = 0, ilen = this.m_PolyOuts.length; i < ilen; i++) {
            var outRec = this.m_PolyOuts[i];

            if (outRec.Pts !== null && outRec.FirstLeft == OldOutRec) {
              if (this.Poly2ContainsPoly1(outRec.Pts, NewOutRec.Pts)) outRec.FirstLeft = NewOutRec;
            }
          }
        };

        ClipperLib.Clipper.prototype.FixupFirstLefts2 = function (OldOutRec, NewOutRec) {
          for (var $i2 = 0, $t2 = this.m_PolyOuts, $l2 = $t2.length, outRec = $t2[$i2]; $i2 < $l2; $i2++, outRec = $t2[$i2]) if (outRec.FirstLeft == OldOutRec) outRec.FirstLeft = NewOutRec;
        };

        ClipperLib.Clipper.ParseFirstLeft = function (FirstLeft) {
          while (FirstLeft != null && FirstLeft.Pts == null) FirstLeft = FirstLeft.FirstLeft;

          return FirstLeft;
        };

        ClipperLib.Clipper.prototype.JoinCommonEdges = function () {
          for (var i = 0, ilen = this.m_Joins.length; i < ilen; i++) {
            var join = this.m_Joins[i];
            var outRec1 = this.GetOutRec(join.OutPt1.Idx);
            var outRec2 = this.GetOutRec(join.OutPt2.Idx);
            if (outRec1.Pts == null || outRec2.Pts == null) continue; //get the polygon fragment with the correct hole state (FirstLeft)
            //before calling JoinPoints() ...

            var holeStateRec;
            if (outRec1 == outRec2) holeStateRec = outRec1;else if (this.Param1RightOfParam2(outRec1, outRec2)) holeStateRec = outRec2;else if (this.Param1RightOfParam2(outRec2, outRec1)) holeStateRec = outRec1;else holeStateRec = this.GetLowermostRec(outRec1, outRec2);
            if (!this.JoinPoints(join, outRec1, outRec2)) continue;

            if (outRec1 == outRec2) {
              //instead of joining two polygons, we've just created a new one by
              //splitting one polygon into two.
              outRec1.Pts = join.OutPt1;
              outRec1.BottomPt = null;
              outRec2 = this.CreateOutRec();
              outRec2.Pts = join.OutPt2; //update all OutRec2.Pts Idx's ...

              this.UpdateOutPtIdxs(outRec2); //We now need to check every OutRec.FirstLeft pointer. If it points
              //to OutRec1 it may need to point to OutRec2 instead ...

              if (this.m_UsingPolyTree) for (var j = 0, jlen = this.m_PolyOuts.length; j < jlen - 1; j++) {
                var oRec = this.m_PolyOuts[j];
                if (oRec.Pts == null || ClipperLib.Clipper.ParseFirstLeft(oRec.FirstLeft) != outRec1 || oRec.IsHole == outRec1.IsHole) continue;
                if (this.Poly2ContainsPoly1(oRec.Pts, join.OutPt2)) oRec.FirstLeft = outRec2;
              }

              if (this.Poly2ContainsPoly1(outRec2.Pts, outRec1.Pts)) {
                //outRec2 is contained by outRec1 ...
                outRec2.IsHole = !outRec1.IsHole;
                outRec2.FirstLeft = outRec1; //fixup FirstLeft pointers that may need reassigning to OutRec1

                if (this.m_UsingPolyTree) this.FixupFirstLefts2(outRec2, outRec1);
                if ((outRec2.IsHole ^ this.ReverseSolution) == this.Area(outRec2) > 0) this.ReversePolyPtLinks(outRec2.Pts);
              } else if (this.Poly2ContainsPoly1(outRec1.Pts, outRec2.Pts)) {
                //outRec1 is contained by outRec2 ...
                outRec2.IsHole = outRec1.IsHole;
                outRec1.IsHole = !outRec2.IsHole;
                outRec2.FirstLeft = outRec1.FirstLeft;
                outRec1.FirstLeft = outRec2; //fixup FirstLeft pointers that may need reassigning to OutRec1

                if (this.m_UsingPolyTree) this.FixupFirstLefts2(outRec1, outRec2);
                if ((outRec1.IsHole ^ this.ReverseSolution) == this.Area(outRec1) > 0) this.ReversePolyPtLinks(outRec1.Pts);
              } else {
                //the 2 polygons are completely separate ...
                outRec2.IsHole = outRec1.IsHole;
                outRec2.FirstLeft = outRec1.FirstLeft; //fixup FirstLeft pointers that may need reassigning to OutRec2

                if (this.m_UsingPolyTree) this.FixupFirstLefts1(outRec1, outRec2);
              }
            } else {
              //joined 2 polygons together ...
              outRec2.Pts = null;
              outRec2.BottomPt = null;
              outRec2.Idx = outRec1.Idx;
              outRec1.IsHole = holeStateRec.IsHole;
              if (holeStateRec == outRec2) outRec1.FirstLeft = outRec2.FirstLeft;
              outRec2.FirstLeft = outRec1; //fixup FirstLeft pointers that may need reassigning to OutRec1

              if (this.m_UsingPolyTree) this.FixupFirstLefts2(outRec2, outRec1);
            }
          }
        };

        ClipperLib.Clipper.prototype.UpdateOutPtIdxs = function (outrec) {
          var op = outrec.Pts;

          do {
            op.Idx = outrec.Idx;
            op = op.Prev;
          } while (op != outrec.Pts);
        };

        ClipperLib.Clipper.prototype.DoSimplePolygons = function () {
          var i = 0;

          while (i < this.m_PolyOuts.length) {
            var outrec = this.m_PolyOuts[i++];
            var op = outrec.Pts;
            if (op === null) continue;

            do //for each Pt in Polygon until duplicate found do ...
            {
              var op2 = op.Next;

              while (op2 != outrec.Pts) {
                if (ClipperLib.IntPoint.op_Equality(op.Pt, op2.Pt) && op2.Next != op && op2.Prev != op) {
                  //split the polygon into two ...
                  var op3 = op.Prev;
                  var op4 = op2.Prev;
                  op.Prev = op4;
                  op4.Next = op;
                  op2.Prev = op3;
                  op3.Next = op2;
                  outrec.Pts = op;
                  var outrec2 = this.CreateOutRec();
                  outrec2.Pts = op2;
                  this.UpdateOutPtIdxs(outrec2);

                  if (this.Poly2ContainsPoly1(outrec2.Pts, outrec.Pts)) {
                    //OutRec2 is contained by OutRec1 ...
                    outrec2.IsHole = !outrec.IsHole;
                    outrec2.FirstLeft = outrec;
                  } else if (this.Poly2ContainsPoly1(outrec.Pts, outrec2.Pts)) {
                    //OutRec1 is contained by OutRec2 ...
                    outrec2.IsHole = outrec.IsHole;
                    outrec.IsHole = !outrec2.IsHole;
                    outrec2.FirstLeft = outrec.FirstLeft;
                    outrec.FirstLeft = outrec2;
                  } else {
                    //the 2 polygons are separate ...
                    outrec2.IsHole = outrec.IsHole;
                    outrec2.FirstLeft = outrec.FirstLeft;
                  }

                  op2 = op; //ie get ready for the next iteration
                }

                op2 = op2.Next;
              }

              op = op.Next;
            } while (op != outrec.Pts);
          }
        };

        ClipperLib.Clipper.Area = function (poly) {
          var cnt = poly.length;
          if (cnt < 3) return 0;
          var a = 0;

          for (var i = 0, j = cnt - 1; i < cnt; ++i) {
            a += (poly[j].X + poly[i].X) * (poly[j].Y - poly[i].Y);
            j = i;
          }

          return -a * 0.5;
        };

        ClipperLib.Clipper.prototype.Area = function (outRec) {
          var op = outRec.Pts;
          if (op == null) return 0;
          var a = 0;

          do {
            a = a + (op.Prev.Pt.X + op.Pt.X) * (op.Prev.Pt.Y - op.Pt.Y);
            op = op.Next;
          } while (op != outRec.Pts);

          return a * 0.5;
        };

        ClipperLib.Clipper.SimplifyPolygon = function (poly, fillType) {
          var result = new Array();
          var c = new ClipperLib.Clipper(0);
          c.StrictlySimple = true;
          c.AddPath(poly, ClipperLib.PolyType.ptSubject, true);
          c.Execute(ClipperLib.ClipType.ctUnion, result, fillType, fillType);
          return result;
        };

        ClipperLib.Clipper.SimplifyPolygons = function (polys, fillType) {
          if (typeof fillType == "undefined") fillType = ClipperLib.PolyFillType.pftEvenOdd;
          var result = new Array();
          var c = new ClipperLib.Clipper(0);
          c.StrictlySimple = true;
          c.AddPaths(polys, ClipperLib.PolyType.ptSubject, true);
          c.Execute(ClipperLib.ClipType.ctUnion, result, fillType, fillType);
          return result;
        };

        ClipperLib.Clipper.DistanceSqrd = function (pt1, pt2) {
          var dx = pt1.X - pt2.X;
          var dy = pt1.Y - pt2.Y;
          return dx * dx + dy * dy;
        };

        ClipperLib.Clipper.DistanceFromLineSqrd = function (pt, ln1, ln2) {
          //The equation of a line in general form (Ax + By + C = 0)
          //given 2 points (x�,y�) & (x�,y�) is ...
          //(y� - y�)x + (x� - x�)y + (y� - y�)x� - (x� - x�)y� = 0
          //A = (y� - y�); B = (x� - x�); C = (y� - y�)x� - (x� - x�)y�
          //perpendicular distance of point (x�,y�) = (Ax� + By� + C)/Sqrt(A� + B�)
          //see http://en.wikipedia.org/wiki/Perpendicular_distance
          var A = ln1.Y - ln2.Y;
          var B = ln2.X - ln1.X;
          var C = A * ln1.X + B * ln1.Y;
          C = A * pt.X + B * pt.Y - C;
          return C * C / (A * A + B * B);
        };

        ClipperLib.Clipper.SlopesNearCollinear = function (pt1, pt2, pt3, distSqrd) {
          return ClipperLib.Clipper.DistanceFromLineSqrd(pt2, pt1, pt3) < distSqrd;
        };

        ClipperLib.Clipper.PointsAreClose = function (pt1, pt2, distSqrd) {
          var dx = pt1.X - pt2.X;
          var dy = pt1.Y - pt2.Y;
          return dx * dx + dy * dy <= distSqrd;
        }; //------------------------------------------------------------------------------


        ClipperLib.Clipper.ExcludeOp = function (op) {
          var result = op.Prev;
          result.Next = op.Next;
          op.Next.Prev = result;
          result.Idx = 0;
          return result;
        };

        ClipperLib.Clipper.CleanPolygon = function (path, distance) {
          if (typeof distance == "undefined") distance = 1.415; //distance = proximity in units/pixels below which vertices will be stripped. 
          //Default ~= sqrt(2) so when adjacent vertices or semi-adjacent vertices have 
          //both x & y coords within 1 unit, then the second vertex will be stripped.

          var cnt = path.length;
          if (cnt == 0) return new Array();
          var outPts = new Array(cnt);

          for (var i = 0; i < cnt; ++i) outPts[i] = new ClipperLib.OutPt();

          for (var i = 0; i < cnt; ++i) {
            outPts[i].Pt = path[i];
            outPts[i].Next = outPts[(i + 1) % cnt];
            outPts[i].Next.Prev = outPts[i];
            outPts[i].Idx = 0;
          }

          var distSqrd = distance * distance;
          var op = outPts[0];

          while (op.Idx == 0 && op.Next != op.Prev) {
            if (ClipperLib.Clipper.PointsAreClose(op.Pt, op.Prev.Pt, distSqrd)) {
              op = ClipperLib.Clipper.ExcludeOp(op);
              cnt--;
            } else if (ClipperLib.Clipper.PointsAreClose(op.Prev.Pt, op.Next.Pt, distSqrd)) {
              ClipperLib.Clipper.ExcludeOp(op.Next);
              op = ClipperLib.Clipper.ExcludeOp(op);
              cnt -= 2;
            } else if (ClipperLib.Clipper.SlopesNearCollinear(op.Prev.Pt, op.Pt, op.Next.Pt, distSqrd)) {
              op = ClipperLib.Clipper.ExcludeOp(op);
              cnt--;
            } else {
              op.Idx = 1;
              op = op.Next;
            }
          }

          if (cnt < 3) cnt = 0;
          var result = new Array(cnt);

          for (var i = 0; i < cnt; ++i) {
            result[i] = new ClipperLib.IntPoint(op.Pt);
            op = op.Next;
          }

          outPts = null;
          return result;
        };

        ClipperLib.Clipper.CleanPolygons = function (polys, distance) {
          var result = new Array(polys.length);

          for (var i = 0, ilen = polys.length; i < ilen; i++) result[i] = ClipperLib.Clipper.CleanPolygon(polys[i], distance);

          return result;
        };

        ClipperLib.Clipper.Minkowski = function (pattern, path, IsSum, IsClosed) {
          var delta = IsClosed ? 1 : 0;
          var polyCnt = pattern.length;
          var pathCnt = path.length;
          var result = new Array();
          if (IsSum) for (var i = 0; i < pathCnt; i++) {
            var p = new Array(polyCnt);

            for (var j = 0, jlen = pattern.length, ip = pattern[j]; j < jlen; j++, ip = pattern[j]) p[j] = new ClipperLib.IntPoint(path[i].X + ip.X, path[i].Y + ip.Y);

            result.push(p);
          } else for (var i = 0; i < pathCnt; i++) {
            var p = new Array(polyCnt);

            for (var j = 0, jlen = pattern.length, ip = pattern[j]; j < jlen; j++, ip = pattern[j]) p[j] = new ClipperLib.IntPoint(path[i].X - ip.X, path[i].Y - ip.Y);

            result.push(p);
          }
          var quads = new Array();

          for (var i = 0; i < pathCnt - 1 + delta; i++) for (var j = 0; j < polyCnt; j++) {
            var quad = new Array();
            quad.push(result[i % pathCnt][j % polyCnt]);
            quad.push(result[(i + 1) % pathCnt][j % polyCnt]);
            quad.push(result[(i + 1) % pathCnt][(j + 1) % polyCnt]);
            quad.push(result[i % pathCnt][(j + 1) % polyCnt]);
            if (!ClipperLib.Clipper.Orientation(quad)) quad.reverse();
            quads.push(quad);
          }

          var c = new ClipperLib.Clipper(0);
          c.AddPaths(quads, ClipperLib.PolyType.ptSubject, true);
          c.Execute(ClipperLib.ClipType.ctUnion, result, ClipperLib.PolyFillType.pftNonZero, ClipperLib.PolyFillType.pftNonZero);
          return result;
        };

        ClipperLib.Clipper.MinkowskiSum = function () {
          var a = arguments,
              alen = a.length;

          if (alen == 3) // MinkowskiSum(Path pattern, path, pathIsClosed)
            {
              var pattern = a[0],
                  path = a[1],
                  pathIsClosed = a[2];
              return ClipperLib.Clipper.Minkowski(pattern, path, true, pathIsClosed);
            } else if (alen == 4) // MinkowskiSum(pattern, paths, pathFillType, pathIsClosed)
            {
              var pattern = a[0],
                  paths = a[1],
                  pathFillType = a[2],
                  pathIsClosed = a[3];
              var c = new ClipperLib.Clipper(),
                  tmp;

              for (var i = 0, ilen = paths.length; i < ilen; ++i) {
                var tmp = ClipperLib.Clipper.Minkowski(pattern, paths[i], true, pathIsClosed);
                c.AddPaths(tmp, ClipperLib.PolyType.ptSubject, true);
              }

              if (pathIsClosed) c.AddPaths(paths, ClipperLib.PolyType.ptClip, true);
              var solution = new ClipperLib.Paths();
              c.Execute(ClipperLib.ClipType.ctUnion, solution, pathFillType, pathFillType);
              return solution;
            }
        };

        ClipperLib.Clipper.MinkowskiDiff = function (pattern, path, pathIsClosed) {
          return ClipperLib.Clipper.Minkowski(pattern, path, false, pathIsClosed);
        };

        ClipperLib.Clipper.PolyTreeToPaths = function (polytree) {
          var result = new Array(); //result.set_Capacity(polytree.get_Total());

          ClipperLib.Clipper.AddPolyNodeToPaths(polytree, ClipperLib.Clipper.NodeType.ntAny, result);
          return result;
        };

        ClipperLib.Clipper.AddPolyNodeToPaths = function (polynode, nt, paths) {
          var match = true;

          switch (nt) {
            case ClipperLib.Clipper.NodeType.ntOpen:
              return;

            case ClipperLib.Clipper.NodeType.ntClosed:
              match = !polynode.IsOpen;
              break;
          }

          if (polynode.m_polygon.length > 0 && match) paths.push(polynode.m_polygon);

          for (var $i3 = 0, $t3 = polynode.Childs(), $l3 = $t3.length, pn = $t3[$i3]; $i3 < $l3; $i3++, pn = $t3[$i3]) ClipperLib.Clipper.AddPolyNodeToPaths(pn, nt, paths);
        };

        ClipperLib.Clipper.OpenPathsFromPolyTree = function (polytree) {
          var result = new ClipperLib.Paths(); //result.set_Capacity(polytree.ChildCount());

          for (var i = 0, ilen = polytree.ChildCount(); i < ilen; i++) if (polytree.Childs()[i].IsOpen) result.push(polytree.Childs()[i].m_polygon);

          return result;
        };

        ClipperLib.Clipper.ClosedPathsFromPolyTree = function (polytree) {
          var result = new ClipperLib.Paths(); //result.set_Capacity(polytree.Total());

          ClipperLib.Clipper.AddPolyNodeToPaths(polytree, ClipperLib.Clipper.NodeType.ntClosed, result);
          return result;
        };

        Inherit(ClipperLib.Clipper, ClipperLib.ClipperBase);
        ClipperLib.Clipper.NodeType = {
          ntAny: 0,
          ntOpen: 1,
          ntClosed: 2
        };

        ClipperLib.ClipperOffset = function (miterLimit, arcTolerance) {
          if (typeof miterLimit == "undefined") miterLimit = 2;
          if (typeof arcTolerance == "undefined") arcTolerance = ClipperLib.ClipperOffset.def_arc_tolerance;
          this.m_destPolys = new ClipperLib.Paths();
          this.m_srcPoly = new ClipperLib.Path();
          this.m_destPoly = new ClipperLib.Path();
          this.m_normals = new Array();
          this.m_delta = 0;
          this.m_sinA = 0;
          this.m_sin = 0;
          this.m_cos = 0;
          this.m_miterLim = 0;
          this.m_StepsPerRad = 0;
          this.m_lowest = new ClipperLib.IntPoint();
          this.m_polyNodes = new ClipperLib.PolyNode();
          this.MiterLimit = miterLimit;
          this.ArcTolerance = arcTolerance;
          this.m_lowest.X = -1;
        };

        ClipperLib.ClipperOffset.two_pi = 6.28318530717959;
        ClipperLib.ClipperOffset.def_arc_tolerance = 0.25;

        ClipperLib.ClipperOffset.prototype.Clear = function () {
          ClipperLib.Clear(this.m_polyNodes.Childs());
          this.m_lowest.X = -1;
        };

        ClipperLib.ClipperOffset.Round = ClipperLib.Clipper.Round;

        ClipperLib.ClipperOffset.prototype.AddPath = function (path, joinType, endType) {
          var highI = path.length - 1;
          if (highI < 0) return;
          var newNode = new ClipperLib.PolyNode();
          newNode.m_jointype = joinType;
          newNode.m_endtype = endType; //strip duplicate points from path and also get index to the lowest point ...

          if (endType == ClipperLib.EndType.etClosedLine || endType == ClipperLib.EndType.etClosedPolygon) while (highI > 0 && ClipperLib.IntPoint.op_Equality(path[0], path[highI])) highI--; //newNode.m_polygon.set_Capacity(highI + 1);

          newNode.m_polygon.push(path[0]);
          var j = 0,
              k = 0;

          for (var i = 1; i <= highI; i++) if (ClipperLib.IntPoint.op_Inequality(newNode.m_polygon[j], path[i])) {
            j++;
            newNode.m_polygon.push(path[i]);
            if (path[i].Y > newNode.m_polygon[k].Y || path[i].Y == newNode.m_polygon[k].Y && path[i].X < newNode.m_polygon[k].X) k = j;
          }

          if (endType == ClipperLib.EndType.etClosedPolygon && j < 2 || endType != ClipperLib.EndType.etClosedPolygon && j < 0) return;
          this.m_polyNodes.AddChild(newNode); //if this path's lowest pt is lower than all the others then update m_lowest

          if (endType != ClipperLib.EndType.etClosedPolygon) return;
          if (this.m_lowest.X < 0) this.m_lowest = new ClipperLib.IntPoint(0, k);else {
            var ip = this.m_polyNodes.Childs()[this.m_lowest.X].m_polygon[this.m_lowest.Y];
            if (newNode.m_polygon[k].Y > ip.Y || newNode.m_polygon[k].Y == ip.Y && newNode.m_polygon[k].X < ip.X) this.m_lowest = new ClipperLib.IntPoint(this.m_polyNodes.ChildCount() - 1, k);
          }
        };

        ClipperLib.ClipperOffset.prototype.AddPaths = function (paths, joinType, endType) {
          for (var i = 0, ilen = paths.length; i < ilen; i++) this.AddPath(paths[i], joinType, endType);
        };

        ClipperLib.ClipperOffset.prototype.FixOrientations = function () {
          //fixup orientations of all closed paths if the orientation of the
          //closed path with the lowermost vertex is wrong ...
          if (this.m_lowest.X >= 0 && !ClipperLib.Clipper.Orientation(this.m_polyNodes.Childs()[this.m_lowest.X].m_polygon)) {
            for (var i = 0; i < this.m_polyNodes.ChildCount(); i++) {
              var node = this.m_polyNodes.Childs()[i];
              if (node.m_endtype == ClipperLib.EndType.etClosedPolygon || node.m_endtype == ClipperLib.EndType.etClosedLine && ClipperLib.Clipper.Orientation(node.m_polygon)) node.m_polygon.reverse();
            }
          } else {
            for (var i = 0; i < this.m_polyNodes.ChildCount(); i++) {
              var node = this.m_polyNodes.Childs()[i];
              if (node.m_endtype == ClipperLib.EndType.etClosedLine && !ClipperLib.Clipper.Orientation(node.m_polygon)) node.m_polygon.reverse();
            }
          }
        };

        ClipperLib.ClipperOffset.GetUnitNormal = function (pt1, pt2) {
          var dx = pt2.X - pt1.X;
          var dy = pt2.Y - pt1.Y;
          if (dx == 0 && dy == 0) return new ClipperLib.DoublePoint(0, 0);
          var f = 1 / Math.sqrt(dx * dx + dy * dy);
          dx *= f;
          dy *= f;
          return new ClipperLib.DoublePoint(dy, -dx);
        };

        ClipperLib.ClipperOffset.prototype.DoOffset = function (delta) {
          this.m_destPolys = new Array();
          this.m_delta = delta; //if Zero offset, just copy any CLOSED polygons to m_p and return ...

          if (ClipperLib.ClipperBase.near_zero(delta)) {
            //this.m_destPolys.set_Capacity(this.m_polyNodes.ChildCount);
            for (var i = 0; i < this.m_polyNodes.ChildCount(); i++) {
              var node = this.m_polyNodes.Childs()[i];
              if (node.m_endtype == ClipperLib.EndType.etClosedPolygon) this.m_destPolys.push(node.m_polygon);
            }

            return;
          } //see offset_triginometry3.svg in the documentation folder ...


          if (this.MiterLimit > 2) this.m_miterLim = 2 / (this.MiterLimit * this.MiterLimit);else this.m_miterLim = 0.5;
          var y;
          if (this.ArcTolerance <= 0) y = ClipperLib.ClipperOffset.def_arc_tolerance;else if (this.ArcTolerance > Math.abs(delta) * ClipperLib.ClipperOffset.def_arc_tolerance) y = Math.abs(delta) * ClipperLib.ClipperOffset.def_arc_tolerance;else y = this.ArcTolerance; //see offset_triginometry2.svg in the documentation folder ...

          var steps = 3.14159265358979 / Math.acos(1 - y / Math.abs(delta));
          this.m_sin = Math.sin(ClipperLib.ClipperOffset.two_pi / steps);
          this.m_cos = Math.cos(ClipperLib.ClipperOffset.two_pi / steps);
          this.m_StepsPerRad = steps / ClipperLib.ClipperOffset.two_pi;
          if (delta < 0) this.m_sin = -this.m_sin; //this.m_destPolys.set_Capacity(this.m_polyNodes.ChildCount * 2);

          for (var i = 0; i < this.m_polyNodes.ChildCount(); i++) {
            var node = this.m_polyNodes.Childs()[i];
            this.m_srcPoly = node.m_polygon;
            var len = this.m_srcPoly.length;
            if (len == 0 || delta <= 0 && (len < 3 || node.m_endtype != ClipperLib.EndType.etClosedPolygon)) continue;
            this.m_destPoly = new Array();

            if (len == 1) {
              if (node.m_jointype == ClipperLib.JoinType.jtRound) {
                var X = 1,
                    Y = 0;

                for (var j = 1; j <= steps; j++) {
                  this.m_destPoly.push(new ClipperLib.IntPoint(ClipperLib.ClipperOffset.Round(this.m_srcPoly[0].X + X * delta), ClipperLib.ClipperOffset.Round(this.m_srcPoly[0].Y + Y * delta)));
                  var X2 = X;
                  X = X * this.m_cos - this.m_sin * Y;
                  Y = X2 * this.m_sin + Y * this.m_cos;
                }
              } else {
                var X = -1,
                    Y = -1;

                for (var j = 0; j < 4; ++j) {
                  this.m_destPoly.push(new ClipperLib.IntPoint(ClipperLib.ClipperOffset.Round(this.m_srcPoly[0].X + X * delta), ClipperLib.ClipperOffset.Round(this.m_srcPoly[0].Y + Y * delta)));
                  if (X < 0) X = 1;else if (Y < 0) Y = 1;else X = -1;
                }
              }

              this.m_destPolys.push(this.m_destPoly);
              continue;
            } //build m_normals ...


            this.m_normals.length = 0; //this.m_normals.set_Capacity(len);

            for (var j = 0; j < len - 1; j++) this.m_normals.push(ClipperLib.ClipperOffset.GetUnitNormal(this.m_srcPoly[j], this.m_srcPoly[j + 1]));

            if (node.m_endtype == ClipperLib.EndType.etClosedLine || node.m_endtype == ClipperLib.EndType.etClosedPolygon) this.m_normals.push(ClipperLib.ClipperOffset.GetUnitNormal(this.m_srcPoly[len - 1], this.m_srcPoly[0]));else this.m_normals.push(new ClipperLib.DoublePoint(this.m_normals[len - 2]));

            if (node.m_endtype == ClipperLib.EndType.etClosedPolygon) {
              var k = len - 1;

              for (var j = 0; j < len; j++) k = this.OffsetPoint(j, k, node.m_jointype);

              this.m_destPolys.push(this.m_destPoly);
            } else if (node.m_endtype == ClipperLib.EndType.etClosedLine) {
              var k = len - 1;

              for (var j = 0; j < len; j++) k = this.OffsetPoint(j, k, node.m_jointype);

              this.m_destPolys.push(this.m_destPoly);
              this.m_destPoly = new Array(); //re-build m_normals ...

              var n = this.m_normals[len - 1];

              for (var j = len - 1; j > 0; j--) this.m_normals[j] = new ClipperLib.DoublePoint(-this.m_normals[j - 1].X, -this.m_normals[j - 1].Y);

              this.m_normals[0] = new ClipperLib.DoublePoint(-n.X, -n.Y);
              k = 0;

              for (var j = len - 1; j >= 0; j--) k = this.OffsetPoint(j, k, node.m_jointype);

              this.m_destPolys.push(this.m_destPoly);
            } else {
              var k = 0;

              for (var j = 1; j < len - 1; ++j) k = this.OffsetPoint(j, k, node.m_jointype);

              var pt1;

              if (node.m_endtype == ClipperLib.EndType.etOpenButt) {
                var j = len - 1;
                pt1 = new ClipperLib.IntPoint(ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].X + this.m_normals[j].X * delta), ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].Y + this.m_normals[j].Y * delta));
                this.m_destPoly.push(pt1);
                pt1 = new ClipperLib.IntPoint(ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].X - this.m_normals[j].X * delta), ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].Y - this.m_normals[j].Y * delta));
                this.m_destPoly.push(pt1);
              } else {
                var j = len - 1;
                k = len - 2;
                this.m_sinA = 0;
                this.m_normals[j] = new ClipperLib.DoublePoint(-this.m_normals[j].X, -this.m_normals[j].Y);
                if (node.m_endtype == ClipperLib.EndType.etOpenSquare) this.DoSquare(j, k);else this.DoRound(j, k);
              } //re-build m_normals ...


              for (var j = len - 1; j > 0; j--) this.m_normals[j] = new ClipperLib.DoublePoint(-this.m_normals[j - 1].X, -this.m_normals[j - 1].Y);

              this.m_normals[0] = new ClipperLib.DoublePoint(-this.m_normals[1].X, -this.m_normals[1].Y);
              k = len - 1;

              for (var j = k - 1; j > 0; --j) k = this.OffsetPoint(j, k, node.m_jointype);

              if (node.m_endtype == ClipperLib.EndType.etOpenButt) {
                pt1 = new ClipperLib.IntPoint(ClipperLib.ClipperOffset.Round(this.m_srcPoly[0].X - this.m_normals[0].X * delta), ClipperLib.ClipperOffset.Round(this.m_srcPoly[0].Y - this.m_normals[0].Y * delta));
                this.m_destPoly.push(pt1);
                pt1 = new ClipperLib.IntPoint(ClipperLib.ClipperOffset.Round(this.m_srcPoly[0].X + this.m_normals[0].X * delta), ClipperLib.ClipperOffset.Round(this.m_srcPoly[0].Y + this.m_normals[0].Y * delta));
                this.m_destPoly.push(pt1);
              } else {
                k = 1;
                this.m_sinA = 0;
                if (node.m_endtype == ClipperLib.EndType.etOpenSquare) this.DoSquare(0, 1);else this.DoRound(0, 1);
              }

              this.m_destPolys.push(this.m_destPoly);
            }
          }
        };

        ClipperLib.ClipperOffset.prototype.Execute = function () {
          var a = arguments,
              ispolytree = a[0] instanceof ClipperLib.PolyTree;

          if (!ispolytree) // function (solution, delta)
            {
              var solution = a[0],
                  delta = a[1];
              ClipperLib.Clear(solution);
              this.FixOrientations();
              this.DoOffset(delta); //now clean up 'corners' ...

              var clpr = new ClipperLib.Clipper(0);
              clpr.AddPaths(this.m_destPolys, ClipperLib.PolyType.ptSubject, true);

              if (delta > 0) {
                clpr.Execute(ClipperLib.ClipType.ctUnion, solution, ClipperLib.PolyFillType.pftPositive, ClipperLib.PolyFillType.pftPositive);
              } else {
                var r = ClipperLib.Clipper.GetBounds(this.m_destPolys);
                var outer = new ClipperLib.Path();
                outer.push(new ClipperLib.IntPoint(r.left - 10, r.bottom + 10));
                outer.push(new ClipperLib.IntPoint(r.right + 10, r.bottom + 10));
                outer.push(new ClipperLib.IntPoint(r.right + 10, r.top - 10));
                outer.push(new ClipperLib.IntPoint(r.left - 10, r.top - 10));
                clpr.AddPath(outer, ClipperLib.PolyType.ptSubject, true);
                clpr.ReverseSolution = true;
                clpr.Execute(ClipperLib.ClipType.ctUnion, solution, ClipperLib.PolyFillType.pftNegative, ClipperLib.PolyFillType.pftNegative);
                if (solution.length > 0) solution.splice(0, 1);
              } //console.log(JSON.stringify(solution));

            } else // function (polytree, delta)
            {
              var solution = a[0],
                  delta = a[1];
              solution.Clear();
              this.FixOrientations();
              this.DoOffset(delta); //now clean up 'corners' ...

              var clpr = new ClipperLib.Clipper(0);
              clpr.AddPaths(this.m_destPolys, ClipperLib.PolyType.ptSubject, true);

              if (delta > 0) {
                clpr.Execute(ClipperLib.ClipType.ctUnion, solution, ClipperLib.PolyFillType.pftPositive, ClipperLib.PolyFillType.pftPositive);
              } else {
                var r = ClipperLib.Clipper.GetBounds(this.m_destPolys);
                var outer = new ClipperLib.Path();
                outer.push(new ClipperLib.IntPoint(r.left - 10, r.bottom + 10));
                outer.push(new ClipperLib.IntPoint(r.right + 10, r.bottom + 10));
                outer.push(new ClipperLib.IntPoint(r.right + 10, r.top - 10));
                outer.push(new ClipperLib.IntPoint(r.left - 10, r.top - 10));
                clpr.AddPath(outer, ClipperLib.PolyType.ptSubject, true);
                clpr.ReverseSolution = true;
                clpr.Execute(ClipperLib.ClipType.ctUnion, solution, ClipperLib.PolyFillType.pftNegative, ClipperLib.PolyFillType.pftNegative); //remove the outer PolyNode rectangle ...

                if (solution.ChildCount() == 1 && solution.Childs()[0].ChildCount() > 0) {
                  var outerNode = solution.Childs()[0]; //solution.Childs.set_Capacity(outerNode.ChildCount);

                  solution.Childs()[0] = outerNode.Childs()[0];

                  for (var i = 1; i < outerNode.ChildCount(); i++) solution.AddChild(outerNode.Childs()[i]);
                } else solution.Clear();
              }
            }
        };

        ClipperLib.ClipperOffset.prototype.OffsetPoint = function (j, k, jointype) {
          this.m_sinA = this.m_normals[k].X * this.m_normals[j].Y - this.m_normals[j].X * this.m_normals[k].Y;
          if (this.m_sinA < 0.00005 && this.m_sinA > -0.00005) return k;else if (this.m_sinA > 1) this.m_sinA = 1.0;else if (this.m_sinA < -1) this.m_sinA = -1.0;

          if (this.m_sinA * this.m_delta < 0) {
            this.m_destPoly.push(new ClipperLib.IntPoint(ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].X + this.m_normals[k].X * this.m_delta), ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].Y + this.m_normals[k].Y * this.m_delta)));
            this.m_destPoly.push(new ClipperLib.IntPoint(this.m_srcPoly[j]));
            this.m_destPoly.push(new ClipperLib.IntPoint(ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].X + this.m_normals[j].X * this.m_delta), ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].Y + this.m_normals[j].Y * this.m_delta)));
          } else switch (jointype) {
            case ClipperLib.JoinType.jtMiter:
              {
                var r = 1 + (this.m_normals[j].X * this.m_normals[k].X + this.m_normals[j].Y * this.m_normals[k].Y);
                if (r >= this.m_miterLim) this.DoMiter(j, k, r);else this.DoSquare(j, k);
                break;
              }

            case ClipperLib.JoinType.jtSquare:
              this.DoSquare(j, k);
              break;

            case ClipperLib.JoinType.jtRound:
              this.DoRound(j, k);
              break;
          }

          k = j;
          return k;
        };

        ClipperLib.ClipperOffset.prototype.DoSquare = function (j, k) {
          var dx = Math.tan(Math.atan2(this.m_sinA, this.m_normals[k].X * this.m_normals[j].X + this.m_normals[k].Y * this.m_normals[j].Y) / 4);
          this.m_destPoly.push(new ClipperLib.IntPoint(ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].X + this.m_delta * (this.m_normals[k].X - this.m_normals[k].Y * dx)), ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].Y + this.m_delta * (this.m_normals[k].Y + this.m_normals[k].X * dx))));
          this.m_destPoly.push(new ClipperLib.IntPoint(ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].X + this.m_delta * (this.m_normals[j].X + this.m_normals[j].Y * dx)), ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].Y + this.m_delta * (this.m_normals[j].Y - this.m_normals[j].X * dx))));
        };

        ClipperLib.ClipperOffset.prototype.DoMiter = function (j, k, r) {
          var q = this.m_delta / r;
          this.m_destPoly.push(new ClipperLib.IntPoint(ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].X + (this.m_normals[k].X + this.m_normals[j].X) * q), ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].Y + (this.m_normals[k].Y + this.m_normals[j].Y) * q)));
        };

        ClipperLib.ClipperOffset.prototype.DoRound = function (j, k) {
          var a = Math.atan2(this.m_sinA, this.m_normals[k].X * this.m_normals[j].X + this.m_normals[k].Y * this.m_normals[j].Y);
          var steps = ClipperLib.Cast_Int32(ClipperLib.ClipperOffset.Round(this.m_StepsPerRad * Math.abs(a)));
          var X = this.m_normals[k].X,
              Y = this.m_normals[k].Y,
              X2;

          for (var i = 0; i < steps; ++i) {
            this.m_destPoly.push(new ClipperLib.IntPoint(ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].X + X * this.m_delta), ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].Y + Y * this.m_delta)));
            X2 = X;
            X = X * this.m_cos - this.m_sin * Y;
            Y = X2 * this.m_sin + Y * this.m_cos;
          }

          this.m_destPoly.push(new ClipperLib.IntPoint(ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].X + this.m_normals[j].X * this.m_delta), ClipperLib.ClipperOffset.Round(this.m_srcPoly[j].Y + this.m_normals[j].Y * this.m_delta)));
        };

        ClipperLib.Error = function (message) {
          try {
            throw new Error(message);
          } catch (err) {
            alert(err.message);
          }
        }; // ---------------------------------
        // JS extension by Timo 2013


        ClipperLib.JS = {};

        ClipperLib.JS.AreaOfPolygon = function (poly, scale) {
          if (!scale) scale = 1;
          return ClipperLib.Clipper.Area(poly) / (scale * scale);
        };

        ClipperLib.JS.AreaOfPolygons = function (poly, scale) {
          if (!scale) scale = 1;
          var area = 0;

          for (var i = 0; i < poly.length; i++) {
            area += ClipperLib.Clipper.Area(poly[i]);
          }

          return area / (scale * scale);
        };

        ClipperLib.JS.BoundsOfPath = function (path, scale) {
          return ClipperLib.JS.BoundsOfPaths([path], scale);
        };

        ClipperLib.JS.BoundsOfPaths = function (paths, scale) {
          if (!scale) scale = 1;
          var bounds = ClipperLib.Clipper.GetBounds(paths);
          bounds.left /= scale;
          bounds.bottom /= scale;
          bounds.right /= scale;
          bounds.top /= scale;
          return bounds;
        }; // Clean() joins vertices that are too near each other
        // and causes distortion to offsetted polygons without cleaning


        ClipperLib.JS.Clean = function (polygon, delta) {
          if (!(polygon instanceof Array)) return [];
          var isPolygons = polygon[0] instanceof Array;
          var polygon = ClipperLib.JS.Clone(polygon);

          if (typeof delta != "number" || delta === null) {
            ClipperLib.Error("Delta is not a number in Clean().");
            return polygon;
          }

          if (polygon.length === 0 || polygon.length == 1 && polygon[0].length === 0 || delta < 0) return polygon;
          if (!isPolygons) polygon = [polygon];
          var k_length = polygon.length;
          var len, poly, result, d, p, j, i;
          var results = [];

          for (var k = 0; k < k_length; k++) {
            poly = polygon[k];
            len = poly.length;
            if (len === 0) continue;else if (len < 3) {
              result = poly;
              results.push(result);
              continue;
            }
            result = poly;
            d = delta * delta; //d = Math.floor(c_delta * c_delta);

            p = poly[0];
            j = 1;

            for (i = 1; i < len; i++) {
              if ((poly[i].X - p.X) * (poly[i].X - p.X) + (poly[i].Y - p.Y) * (poly[i].Y - p.Y) <= d) continue;
              result[j] = poly[i];
              p = poly[i];
              j++;
            }

            p = poly[j - 1];
            if ((poly[0].X - p.X) * (poly[0].X - p.X) + (poly[0].Y - p.Y) * (poly[0].Y - p.Y) <= d) j--;
            if (j < len) result.splice(j, len - j);
            if (result.length) results.push(result);
          }

          if (!isPolygons && results.length) results = results[0];else if (!isPolygons && results.length === 0) results = [];else if (isPolygons && results.length === 0) results = [[]];
          return results;
        }; // Make deep copy of Polygons or Polygon
        // so that also IntPoint objects are cloned and not only referenced
        // This should be the fastest way


        ClipperLib.JS.Clone = function (polygon) {
          if (!(polygon instanceof Array)) return [];
          if (polygon.length === 0) return [];else if (polygon.length == 1 && polygon[0].length === 0) return [[]];
          var isPolygons = polygon[0] instanceof Array;
          if (!isPolygons) polygon = [polygon];
          var len = polygon.length,
              plen,
              i,
              j,
              result;
          var results = new Array(len);

          for (i = 0; i < len; i++) {
            plen = polygon[i].length;
            result = new Array(plen);

            for (j = 0; j < plen; j++) {
              result[j] = {
                X: polygon[i][j].X,
                Y: polygon[i][j].Y
              };
            }

            results[i] = result;
          }

          if (!isPolygons) results = results[0];
          return results;
        }; // Removes points that doesn't affect much to the visual appearance.
        // If middle point is at or under certain distance (tolerance) of the line segment between 
        // start and end point, the middle point is removed.


        ClipperLib.JS.Lighten = function (polygon, tolerance) {
          if (!(polygon instanceof Array)) return [];

          if (typeof tolerance != "number" || tolerance === null) {
            ClipperLib.Error("Tolerance is not a number in Lighten().");
            return ClipperLib.JS.Clone(polygon);
          }

          if (polygon.length === 0 || polygon.length == 1 && polygon[0].length === 0 || tolerance < 0) {
            return ClipperLib.JS.Clone(polygon);
          }

          if (!(polygon[0] instanceof Array)) polygon = [polygon];
          var i, j, poly, k, poly2, plen, A, B, P, d, rem, addlast;
          var bxax, byay, l, ax, ay;
          var len = polygon.length;
          var toleranceSq = tolerance * tolerance;
          var results = [];

          for (i = 0; i < len; i++) {
            poly = polygon[i];
            plen = poly.length;
            if (plen == 0) continue;

            for (k = 0; k < 1000000; k++) // could be forever loop, but wiser to restrict max repeat count
            {
              poly2 = [];
              plen = poly.length; // the first have to added to the end, if first and last are not the same
              // this way we ensure that also the actual last point can be removed if needed

              if (poly[plen - 1].X != poly[0].X || poly[plen - 1].Y != poly[0].Y) {
                addlast = 1;
                poly.push({
                  X: poly[0].X,
                  Y: poly[0].Y
                });
                plen = poly.length;
              } else addlast = 0;

              rem = []; // Indexes of removed points

              for (j = 0; j < plen - 2; j++) {
                A = poly[j]; // Start point of line segment

                P = poly[j + 1]; // Middle point. This is the one to be removed.

                B = poly[j + 2]; // End point of line segment

                ax = A.X;
                ay = A.Y;
                bxax = B.X - ax;
                byay = B.Y - ay;

                if (bxax !== 0 || byay !== 0) // To avoid Nan, when A==P && P==B. And to avoid peaks (A==B && A!=P), which have lenght, but not area.
                  {
                    l = ((P.X - ax) * bxax + (P.Y - ay) * byay) / (bxax * bxax + byay * byay);

                    if (l > 1) {
                      ax = B.X;
                      ay = B.Y;
                    } else if (l > 0) {
                      ax += bxax * l;
                      ay += byay * l;
                    }
                  }

                bxax = P.X - ax;
                byay = P.Y - ay;
                d = bxax * bxax + byay * byay;

                if (d <= toleranceSq) {
                  rem[j + 1] = 1;
                  j++; // when removed, transfer the pointer to the next one
                }
              } // add all unremoved points to poly2


              poly2.push({
                X: poly[0].X,
                Y: poly[0].Y
              });

              for (j = 1; j < plen - 1; j++) if (!rem[j]) poly2.push({
                X: poly[j].X,
                Y: poly[j].Y
              });

              poly2.push({
                X: poly[plen - 1].X,
                Y: poly[plen - 1].Y
              }); // if the first point was added to the end, remove it

              if (addlast) poly.pop(); // break, if there was not anymore removed points

              if (!rem.length) break; // else continue looping using poly2, to check if there are points to remove
              else poly = poly2;
            }

            plen = poly2.length; // remove duplicate from end, if needed

            if (poly2[plen - 1].X == poly2[0].X && poly2[plen - 1].Y == poly2[0].Y) {
              poly2.pop();
            }

            if (poly2.length > 2) // to avoid two-point-polygons
              results.push(poly2);
          }

          if (!polygon[0] instanceof Array) results = results[0];
          if (typeof results == "undefined") results = [[]];
          return results;
        };

        ClipperLib.JS.PerimeterOfPath = function (path, closed, scale) {
          if (typeof path == "undefined") return 0;
          var sqrt = Math.sqrt;
          var perimeter = 0.0;
          var p1,
              p2,
              p1x = 0.0,
              p1y = 0.0,
              p2x = 0.0,
              p2y = 0.0;
          var j = path.length;
          if (j < 2) return 0;

          if (closed) {
            path[j] = path[0];
            j++;
          }

          while (--j) {
            p1 = path[j];
            p1x = p1.X;
            p1y = p1.Y;
            p2 = path[j - 1];
            p2x = p2.X;
            p2y = p2.Y;
            perimeter += sqrt((p1x - p2x) * (p1x - p2x) + (p1y - p2y) * (p1y - p2y));
          }

          if (closed) path.pop();
          return perimeter / scale;
        };

        ClipperLib.JS.PerimeterOfPaths = function (paths, closed, scale) {
          if (!scale) scale = 1;
          var perimeter = 0;

          for (var i = 0; i < paths.length; i++) {
            perimeter += ClipperLib.JS.PerimeterOfPath(paths[i], closed, scale);
          }

          return perimeter;
        };

        ClipperLib.JS.ScaleDownPath = function (path, scale) {
          var i, p;
          if (!scale) scale = 1;
          i = path.length;

          while (i--) {
            p = path[i];
            p.X = p.X / scale;
            p.Y = p.Y / scale;
          }
        };

        ClipperLib.JS.ScaleDownPaths = function (paths, scale) {
          var i, j, p;
          if (!scale) scale = 1;
          i = paths.length;

          while (i--) {
            j = paths[i].length;

            while (j--) {
              p = paths[i][j];
              p.X = p.X / scale;
              p.Y = p.Y / scale;
            }
          }
        };

        ClipperLib.JS.ScaleUpPath = function (path, scale) {
          var i,
              p,
              round = Math.round;
          if (!scale) scale = 1;
          i = path.length;

          while (i--) {
            p = path[i];
            p.X = round(p.X * scale);
            p.Y = round(p.Y * scale);
          }
        };

        ClipperLib.JS.ScaleUpPaths = function (paths, scale) {
          var i,
              j,
              p,
              round = Math.round;
          if (!scale) scale = 1;
          i = paths.length;

          while (i--) {
            j = paths[i].length;

            while (j--) {
              p = paths[i][j];
              p.X = round(p.X * scale);
              p.Y = round(p.Y * scale);
            }
          }
        };

        ClipperLib.ExPolygons = function () {
          return [];
        };

        ClipperLib.ExPolygon = function () {
          this.outer = null;
          this.holes = null;
        };

        ClipperLib.JS.AddOuterPolyNodeToExPolygons = function (polynode, expolygons) {
          var ep = new ClipperLib.ExPolygon();
          ep.outer = polynode.Contour();
          var childs = polynode.Childs();
          var ilen = childs.length;
          ep.holes = new Array(ilen);
          var node, n, i, j, childs2, jlen;

          for (i = 0; i < ilen; i++) {
            node = childs[i];
            ep.holes[i] = node.Contour(); //Add outer polygons contained by (nested within) holes ...

            for (j = 0, childs2 = node.Childs(), jlen = childs2.length; j < jlen; j++) {
              n = childs2[j];
              ClipperLib.JS.AddOuterPolyNodeToExPolygons(n, expolygons);
            }
          }

          expolygons.push(ep);
        };

        ClipperLib.JS.ExPolygonsToPaths = function (expolygons) {
          var a, i, alen, ilen;
          var paths = new ClipperLib.Paths();

          for (a = 0, alen = expolygons.length; a < alen; a++) {
            paths.push(expolygons[a].outer);

            for (i = 0, ilen = expolygons[a].holes.length; i < ilen; i++) {
              paths.push(expolygons[a].holes[i]);
            }
          }

          return paths;
        };

        ClipperLib.JS.PolyTreeToExPolygons = function (polytree) {
          var expolygons = new ClipperLib.ExPolygons();
          var node, i, childs, ilen;

          for (i = 0, childs = polytree.Childs(), ilen = childs.length; i < ilen; i++) {
            node = childs[i];
            ClipperLib.JS.AddOuterPolyNodeToExPolygons(node, expolygons);
          }

          return expolygons;
        };

        module.exports = ClipperLib; // #endregion ORIGINAL CODE

        _cjsExports = exports('default', module.exports);
      }, {});
    }
  };
});

System.register("chunks:///_virtual/CloudAndStorageData.ts", ['cc'], function (exports) {
  var cclegacy;
  return {
    setters: [function (module) {
      cclegacy = module.cclegacy;
    }],
    execute: function () {
      cclegacy._RF.push({}, "8829fXuGXdMubT7gbnHCqR5", "CloudAndStorageData", undefined);

      var ICloudAndStorageData = exports('ICloudAndStorageData', function ICloudAndStorageData() {});
      var CloudAndStorageDataMergeUtils = exports('CloudAndStorageDataMergeUtils', /*#__PURE__*/function () {
        function CloudAndStorageDataMergeUtils(type) {
          this.Type = void 0;
          this.Type = type;
        }

        var _proto = CloudAndStorageDataMergeUtils.prototype;

        _proto.loadFromJson = function loadFromJson(json) {
          var output = new this.Type();

          if (!json) {
            return output;
          }

          var data = json.json;
          output.fromJsonObj(data);
          return output;
        };

        _proto.loadFromJsonString = function loadFromJsonString(str) {
          var output = new this.Type();

          if (!str) {
            return output;
          }

          var data = JSON.parse(str);
          output.fromJsonObj(data);
          return output;
        }
        /**
         * 远端结果和本地缓存合并，结果会更新到
         * @param output 远端更新
         * @param lcoal 本地缓存
         * @returns 
         */
        ;

        _proto.merge = function merge(output, local) {
          // 根据uid进行合并
          if (output && local) {
            if (output.getUid() === local.getUid()) {
              local.copyResult(output);
            }
          }

          return output;
        };

        return CloudAndStorageDataMergeUtils;
      }());

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/CoinsUpdateScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './GLabelScoreScript.ts', './GameControllerEventType.ts', './MyRoleBag.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, director, Component, GLabelScoreScript, GameControllerEventType, MyRoleBag;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      director = module.director;
      Component = module.Component;
    }, function (module) {
      GLabelScoreScript = module.GLabelScoreScript;
    }, function (module) {
      GameControllerEventType = module.GameControllerEventType;
    }, function (module) {
      MyRoleBag = module.MyRoleBag;
    }],
    execute: function () {
      var _dec, _dec2, _class, _class2, _descriptor;

      cclegacy._RF.push({}, "99e6f9QBwhFOpYyXbeUgjef", "CoinsUpdateScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      /**
       * 监听 金币信息变化
       * 可以设置一个value来进行更新
       */

      var CoinsUpdateScript = exports('CoinsUpdateScript', (_dec = ccclass('CoinsUpdateScript'), _dec2 = property(GLabelScoreScript), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(CoinsUpdateScript, _Component);

        function CoinsUpdateScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "value", _descriptor, _assertThisInitialized(_this));

          return _this;
        }

        var _proto = CoinsUpdateScript.prototype;

        _proto.onLoad = function onLoad() {
          director.on(GameControllerEventType.ROLE_COINS_UPDATE, this.updateCoins, this);
        };

        _proto.update = function update(deltaTime) {};

        _proto.updateCoins = function updateCoins() {
          if (this.value) {
            var rolebag = MyRoleBag.get();

            if (rolebag && rolebag.role) {
              this.value.setScore(rolebag.role.coins);
            }
          }
        };

        return CoinsUpdateScript;
      }(Component), _descriptor = _applyDecoratedDescriptor(_class2.prototype, "value", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/Config.ts", ['cc', './ResourcesUtils.ts', './LoginBase.ts'], function (exports) {
  var cclegacy, ResourcesUtils, GameBaseDataConfig;
  return {
    setters: [function (module) {
      cclegacy = module.cclegacy;
    }, function (module) {
      ResourcesUtils = module.ResourcesUtils;
    }, function (module) {
      GameBaseDataConfig = module.GameBaseDataConfig;
    }],
    execute: function () {
      cclegacy._RF.push({}, "44399tcxcBDjKSD2MZL7LYe", "Config", undefined);

      var Config = exports('Config', /*#__PURE__*/function () {
        function Config() {}
        /**
         * 修改成存储路径和Key的名称，避免重复
         */


        Config.init = function init(onComplete) {
          var GAME_NAME = "game_screw"; // 初始化 缓存路径

          GameBaseDataConfig.getInstance().initByGameName(GAME_NAME); // 资源读取

          ResourcesUtils.loadBundle(onComplete);
        } // 皮肤 prefab
        ;

        return Config;
      }());
      Config.PREFAB_PATH_ROLE_SKIN = "prefabs/roleSkins/"; // 武器 prefab

      Config.PREFAB_PATH_WEAPON = "prefabs/weapons/"; // 关卡奖励

      Config.LEVEL_REWARD = 10;

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/ContactDestroyOther.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc'], function (exports) {
  var _inheritsLoose, cclegacy, _decorator, Collider2D, Contact2DType, Component;

  return {
    setters: [function (module) {
      _inheritsLoose = module.inheritsLoose;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Collider2D = module.Collider2D;
      Contact2DType = module.Contact2DType;
      Component = module.Component;
    }],
    execute: function () {
      var _dec, _class;

      cclegacy._RF.push({}, "6786b79I2ZLuI+rUeAW4Lf0", "ContactDestroyOther", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      /**
       * 其他的node碰到了绑定该Compnent的Node就会消失
       * 被绑定的node需要支持碰撞, 并且支持碰撞回调
       */

      var ContactDestroyOther = exports('ContactDestroyOther', (_dec = ccclass('ContactDestroyOther'), _dec(_class = /*#__PURE__*/function (_Component) {
        _inheritsLoose(ContactDestroyOther, _Component);

        function ContactDestroyOther() {
          return _Component.apply(this, arguments) || this;
        }

        var _proto = ContactDestroyOther.prototype;

        _proto.start = function start() {
          var collider = this.node.getComponent(Collider2D);

          if (collider) {
            collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
          }
        };

        _proto.onBeginContact = function onBeginContact(selfCollider, otherCollider, contact) {
          otherCollider.node.removeFromParent();
          console.log('[collider]', 'remove node', otherCollider.node.name, " because collider with ", selfCollider.node.name);
        };

        return ContactDestroyOther;
      }(Component)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/debug-view-runtime-control.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Node, Color, Canvas, UITransform, instantiate, Label, RichText, Toggle, Button, director, Component;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Node = module.Node;
      Color = module.Color;
      Canvas = module.Canvas;
      UITransform = module.UITransform;
      instantiate = module.instantiate;
      Label = module.Label;
      RichText = module.RichText;
      Toggle = module.Toggle;
      Button = module.Button;
      director = module.director;
      Component = module.Component;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _class, _class2, _descriptor, _descriptor2, _descriptor3;

      cclegacy._RF.push({}, "b2bd1+njXxJxaFY3ymm06WU", "debug-view-runtime-control", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var DebugViewRuntimeControl = exports('DebugViewRuntimeControl', (_dec = ccclass('internal.DebugViewRuntimeControl'), _dec2 = property(Node), _dec3 = property(Node), _dec4 = property(Node), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(DebugViewRuntimeControl, _Component);

        function DebugViewRuntimeControl() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "compositeModeToggle", _descriptor, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "singleModeToggle", _descriptor2, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "EnableAllCompositeModeButton", _descriptor3, _assertThisInitialized(_this));

          _this._single = 0;
          _this.strSingle = ['No Single Debug', 'Vertex Color', 'Vertex Normal', 'Vertex Tangent', 'World Position', 'Vertex Mirror', 'Face Side', 'UV0', 'UV1', 'UV Lightmap', 'Project Depth', 'Linear Depth', 'Fragment Normal', 'Fragment Tangent', 'Fragment Binormal', 'Base Color', 'Diffuse Color', 'Specular Color', 'Transparency', 'Metallic', 'Roughness', 'Specular Intensity', 'IOR', 'Direct Diffuse', 'Direct Specular', 'Direct All', 'Env Diffuse', 'Env Specular', 'Env All', 'Emissive', 'Light Map', 'Shadow', 'AO', 'Fresnel', 'Direct Transmit Diffuse', 'Direct Transmit Specular', 'Env Transmit Diffuse', 'Env Transmit Specular', 'Transmit All', 'Direct Internal Specular', 'Env Internal Specular', 'Internal All', 'Fog'];
          _this.strComposite = ['Direct Diffuse', 'Direct Specular', 'Env Diffuse', 'Env Specular', 'Emissive', 'Light Map', 'Shadow', 'AO', 'Normal Map', 'Fog', 'Tone Mapping', 'Gamma Correction', 'Fresnel', 'Transmit Diffuse', 'Transmit Specular', 'Internal Specular', 'TT'];
          _this.strMisc = ['CSM Layer Coloration', 'Lighting With Albedo'];
          _this.compositeModeToggleList = [];
          _this.singleModeToggleList = [];
          _this.miscModeToggleList = [];
          _this.textComponentList = [];
          _this.labelComponentList = [];
          _this.textContentList = [];
          _this.hideButtonLabel = void 0;
          _this._currentColorIndex = 0;
          _this.strColor = ['<color=#ffffff>', '<color=#000000>', '<color=#ff0000>', '<color=#00ff00>', '<color=#0000ff>'];
          _this.color = [Color.WHITE, Color.BLACK, Color.RED, Color.GREEN, Color.BLUE];
          return _this;
        }

        var _proto = DebugViewRuntimeControl.prototype;

        _proto.start = function start() {
          // get canvas resolution
          var canvas = this.node.parent.getComponent(Canvas);

          if (!canvas) {
            console.error('debug-view-runtime-control should be child of Canvas');
            return;
          }

          var uiTransform = this.node.parent.getComponent(UITransform);
          var halfScreenWidth = uiTransform.width * 0.5;
          var halfScreenHeight = uiTransform.height * 0.5;
          var x = -halfScreenWidth + halfScreenWidth * 0.1,
              y = halfScreenHeight - halfScreenHeight * 0.1;
          var width = 200,
              height = 20; // new nodes

          var miscNode = this.node.getChildByName('MiscMode');
          var buttonNode = instantiate(miscNode);
          buttonNode.parent = this.node;
          buttonNode.name = 'Buttons';
          var titleNode = instantiate(miscNode);
          titleNode.parent = this.node;
          titleNode.name = 'Titles'; // title

          for (var i = 0; i < 2; i++) {
            var newLabel = instantiate(this.EnableAllCompositeModeButton.getChildByName('Label'));
            newLabel.setPosition(x + (i > 0 ? 50 + width * 2 : 150), y, 0.0);
            newLabel.setScale(0.75, 0.75, 0.75);
            newLabel.parent = titleNode;

            var _labelComponent = newLabel.getComponent(Label);

            _labelComponent.string = i ? '----------Composite Mode----------' : '----------Single Mode----------';
            _labelComponent.color = Color.WHITE;
            _labelComponent.overflow = 0;
            this.labelComponentList[this.labelComponentList.length] = _labelComponent;
          }

          y -= height; // single

          var currentRow = 0;

          for (var _i = 0; _i < this.strSingle.length; _i++, currentRow++) {
            if (_i === this.strSingle.length >> 1) {
              x += width;
              currentRow = 0;
            }

            var newNode = _i ? instantiate(this.singleModeToggle) : this.singleModeToggle;
            newNode.setPosition(x, y - height * currentRow, 0.0);
            newNode.setScale(0.5, 0.5, 0.5);
            newNode.parent = this.singleModeToggle.parent;
            var textComponent = newNode.getComponentInChildren(RichText);
            textComponent.string = this.strSingle[_i];
            this.textComponentList[this.textComponentList.length] = textComponent;
            this.textContentList[this.textContentList.length] = textComponent.string;
            newNode.on(Toggle.EventType.TOGGLE, this.toggleSingleMode, this);
            this.singleModeToggleList[_i] = newNode;
          }

          x += width; // buttons

          this.EnableAllCompositeModeButton.setPosition(x + 15, y, 0.0);
          this.EnableAllCompositeModeButton.setScale(0.5, 0.5, 0.5);
          this.EnableAllCompositeModeButton.on(Button.EventType.CLICK, this.enableAllCompositeMode, this);
          this.EnableAllCompositeModeButton.parent = buttonNode;
          var labelComponent = this.EnableAllCompositeModeButton.getComponentInChildren(Label);
          this.labelComponentList[this.labelComponentList.length] = labelComponent;
          var changeColorButton = instantiate(this.EnableAllCompositeModeButton);
          changeColorButton.setPosition(x + 90, y, 0.0);
          changeColorButton.setScale(0.5, 0.5, 0.5);
          changeColorButton.on(Button.EventType.CLICK, this.changeTextColor, this);
          changeColorButton.parent = buttonNode;
          labelComponent = changeColorButton.getComponentInChildren(Label);
          labelComponent.string = 'TextColor';
          this.labelComponentList[this.labelComponentList.length] = labelComponent;
          var HideButton = instantiate(this.EnableAllCompositeModeButton);
          HideButton.setPosition(x + 200, y, 0.0);
          HideButton.setScale(0.5, 0.5, 0.5);
          HideButton.on(Button.EventType.CLICK, this.hideUI, this);
          HideButton.parent = this.node.parent;
          labelComponent = HideButton.getComponentInChildren(Label);
          labelComponent.string = 'Hide UI';
          this.labelComponentList[this.labelComponentList.length] = labelComponent;
          this.hideButtonLabel = labelComponent; // misc

          y -= 40;

          for (var _i2 = 0; _i2 < this.strMisc.length; _i2++) {
            var _newNode = instantiate(this.compositeModeToggle);

            _newNode.setPosition(x, y - height * _i2, 0.0);

            _newNode.setScale(0.5, 0.5, 0.5);

            _newNode.parent = miscNode;

            var _textComponent = _newNode.getComponentInChildren(RichText);

            _textComponent.string = this.strMisc[_i2];
            this.textComponentList[this.textComponentList.length] = _textComponent;
            this.textContentList[this.textContentList.length] = _textComponent.string;

            var toggleComponent = _newNode.getComponent(Toggle);

            toggleComponent.isChecked = _i2 ? true : false;

            _newNode.on(Toggle.EventType.TOGGLE, _i2 ? this.toggleLightingWithAlbedo : this.toggleCSMColoration, this);

            this.miscModeToggleList[_i2] = _newNode;
          } // composite


          y -= 150;

          for (var _i3 = 0; _i3 < this.strComposite.length; _i3++) {
            var _newNode2 = _i3 ? instantiate(this.compositeModeToggle) : this.compositeModeToggle;

            _newNode2.setPosition(x, y - height * _i3, 0.0);

            _newNode2.setScale(0.5, 0.5, 0.5);

            _newNode2.parent = this.compositeModeToggle.parent;

            var _textComponent2 = _newNode2.getComponentInChildren(RichText);

            _textComponent2.string = this.strComposite[_i3];
            this.textComponentList[this.textComponentList.length] = _textComponent2;
            this.textContentList[this.textContentList.length] = _textComponent2.string;

            _newNode2.on(Toggle.EventType.TOGGLE, this.toggleCompositeMode, this);

            this.compositeModeToggleList[_i3] = _newNode2;
          }
        };

        _proto.isTextMatched = function isTextMatched(textUI, textDescription) {
          var tempText = new String(textUI);
          var findIndex = tempText.search('>');

          if (findIndex === -1) {
            return textUI === textDescription;
          } else {
            tempText = tempText.substr(findIndex + 1);
            tempText = tempText.substr(0, tempText.search('<'));
            return tempText === textDescription;
          }
        };

        _proto.toggleSingleMode = function toggleSingleMode(toggle) {
          var debugView = director.root.debugView;
          var textComponent = toggle.getComponentInChildren(RichText);

          for (var i = 0; i < this.strSingle.length; i++) {
            if (this.isTextMatched(textComponent.string, this.strSingle[i])) {
              debugView.singleMode = i;
            }
          }
        };

        _proto.toggleCompositeMode = function toggleCompositeMode(toggle) {
          var debugView = director.root.debugView;
          var textComponent = toggle.getComponentInChildren(RichText);

          for (var i = 0; i < this.strComposite.length; i++) {
            if (this.isTextMatched(textComponent.string, this.strComposite[i])) {
              debugView.enableCompositeMode(i, toggle.isChecked);
            }
          }
        };

        _proto.toggleLightingWithAlbedo = function toggleLightingWithAlbedo(toggle) {
          var debugView = director.root.debugView;
          debugView.lightingWithAlbedo = toggle.isChecked;
        };

        _proto.toggleCSMColoration = function toggleCSMColoration(toggle) {
          var debugView = director.root.debugView;
          debugView.csmLayerColoration = toggle.isChecked;
        };

        _proto.enableAllCompositeMode = function enableAllCompositeMode(button) {
          var debugView = director.root.debugView;
          debugView.enableAllCompositeMode(true);

          for (var i = 0; i < this.compositeModeToggleList.length; i++) {
            var _toggleComponent = this.compositeModeToggleList[i].getComponent(Toggle);

            _toggleComponent.isChecked = true;
          }

          var toggleComponent = this.miscModeToggleList[0].getComponent(Toggle);
          toggleComponent.isChecked = false;
          debugView.csmLayerColoration = false;
          toggleComponent = this.miscModeToggleList[1].getComponent(Toggle);
          toggleComponent.isChecked = true;
          debugView.lightingWithAlbedo = true;
        };

        _proto.hideUI = function hideUI(button) {
          var titleNode = this.node.getChildByName('Titles');
          var activeValue = !titleNode.active;
          this.singleModeToggleList[0].parent.active = activeValue;
          this.miscModeToggleList[0].parent.active = activeValue;
          this.compositeModeToggleList[0].parent.active = activeValue;
          this.EnableAllCompositeModeButton.parent.active = activeValue;
          titleNode.active = activeValue;
          this.hideButtonLabel.string = activeValue ? 'Hide UI' : 'Show UI';
        };

        _proto.changeTextColor = function changeTextColor(button) {
          this._currentColorIndex++;

          if (this._currentColorIndex >= this.strColor.length) {
            this._currentColorIndex = 0;
          }

          for (var i = 0; i < this.textComponentList.length; i++) {
            this.textComponentList[i].string = this.strColor[this._currentColorIndex] + this.textContentList[i] + '</color>';
          }

          for (var _i4 = 0; _i4 < this.labelComponentList.length; _i4++) {
            this.labelComponentList[_i4].color = this.color[this._currentColorIndex];
          }
        };

        _proto.onLoad = function onLoad() {};

        _proto.update = function update(deltaTime) {};

        return DebugViewRuntimeControl;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "compositeModeToggle", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return null;
        }
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "singleModeToggle", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return null;
        }
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "EnableAllCompositeModeButton", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return null;
        }
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/DraggableNode.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, CCBoolean, Vec3, Input, PhysicsSystem2D, UITransform, Component;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      CCBoolean = module.CCBoolean;
      Vec3 = module.Vec3;
      Input = module.Input;
      PhysicsSystem2D = module.PhysicsSystem2D;
      UITransform = module.UITransform;
      Component = module.Component;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _class, _class2, _descriptor, _descriptor2;

      cclegacy._RF.push({}, "1d818AYWxpB5bIskCwFNRWn", "DraggableNode", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      /**
       * targetNode进行监听手势
       * 在父节点内部移动
       */

      var DraggableNode = exports('DraggableNode', (_dec = ccclass('DraggableNode'), _dec2 = property(CCBoolean), _dec3 = property(CCBoolean), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(DraggableNode, _Component);

        function DraggableNode() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;
          _this.targetNode = null;

          _initializerDefineProperty(_this, "debug", _descriptor, _assertThisInitialized(_this)); // 移动的时候关闭碰撞,移动完成打开


          _initializerDefineProperty(_this, "closePhysisWhenDrag", _descriptor2, _assertThisInitialized(_this)); // 移动前的位置


          _this.startPos = new Vec3(0);
          _this.isDragging = false;
          _this.lastPhysicsSystem2DEnable = true;
          _this.newPos = new Vec3(); // 回调

          _this.listener = undefined;
          return _this;
        }

        var _proto = DraggableNode.prototype;

        _proto.onLoad = function onLoad() {
          this.targetNode = this.node;
          this.registerEvent();
        };

        _proto.onDestroy = function onDestroy() {
          this.unregisterEvent();
        };

        _proto.setOnDragListener = function setOnDragListener(listener) {
          this.listener = listener;
        };

        _proto.registerEvent = function registerEvent() {
          this.targetNode.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
          this.targetNode.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
          this.targetNode.on(Input.EventType.TOUCH_END, this.onTouchEnd, this);
          this.targetNode.on(Input.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
        };

        _proto.unregisterEvent = function unregisterEvent() {
          this.targetNode.off(Input.EventType.TOUCH_START, this.onTouchStart, this);
          this.targetNode.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
          this.targetNode.off(Input.EventType.TOUCH_END, this.onTouchEnd, this);
          this.targetNode.off(Input.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
        };

        _proto.onTouchStart = function onTouchStart(event) {
          if (!this.targetNode) {
            return;
          }

          this.isDragging = true;

          if (this.closePhysisWhenDrag) {
            this.lastPhysicsSystem2DEnable = PhysicsSystem2D.instance.enable;
            PhysicsSystem2D.instance.enable = false;
          }

          this.startPos = this.targetNode.getPosition().clone();

          if (this.listener && this.listener.onDragBegin) {
            this.listener.onDragBegin(this.targetNode);
          }
        };

        _proto.onTouchMove = function onTouchMove(event) {
          if (!this.isDragging || !this.targetNode) {
            return;
          }

          var screenPos = new Vec3(event.getUILocation().x, event.getUILocation().y, 0); // to node location

          var touchContainerNodePos = this.node.getParent().getComponent(UITransform).convertToNodeSpaceAR(screenPos);
          this.newPos = touchContainerNodePos;
          this.targetNode.setPosition(this.newPos);

          if (this.debug) {
            console.log("touch move", this.targetNode.name, "new pos ", touchContainerNodePos);
          }

          if (this.listener && this.listener.onDragging) {
            this.listener.onDragging(this.targetNode);
          }
        };

        _proto.onTouchEnd = function onTouchEnd() {
          this.isDragging = false;

          if (this.closePhysisWhenDrag) {
            // 和开始之前保持一致，避免默认是关闭的给打开了
            PhysicsSystem2D.instance.enable = this.lastPhysicsSystem2DEnable;
            PhysicsSystem2D.instance.postUpdate(1); // 避免回到原地

            this.targetNode.setPosition(this.newPos);
          }

          if (this.listener && this.listener.onDragEnd) {
            this.listener.onDragEnd(this.targetNode);
          }
        };

        return DraggableNode;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "debug", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return false;
        }
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "closePhysisWhenDrag", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return true;
        }
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/FlashScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './GLoadingScript.ts', './Config.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Node, director, Component, GLoadingScript, Config;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Node = module.Node;
      director = module.director;
      Component = module.Component;
    }, function (module) {
      GLoadingScript = module.GLoadingScript;
    }, function (module) {
      Config = module.Config;
    }],
    execute: function () {
      var _dec, _dec2, _class, _class2, _descriptor;

      cclegacy._RF.push({}, "765d5y5qWdHJrZ9iWpX8hqi", "FlashScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var FlashScript = exports('FlashScript', (_dec = ccclass('FlashScript'), _dec2 = property(Node), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(FlashScript, _Component);

        function FlashScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "loadingNode", _descriptor, _assertThisInitialized(_this));

          return _this;
        }

        var _proto = FlashScript.prototype;

        _proto.start = function start() {
          var _this2 = this;

          this.loadingNode.getComponent(GLoadingScript).updateProgress(90); // 避免重复

          Config.init(function () {
            _this2.loadingNode.getComponent(GLoadingScript).updateProgress(100);

            director.loadScene('home');
          });
        };

        _proto.update = function update(deltaTime) {};

        return FlashScript;
      }(Component), _descriptor = _applyDecoratedDescriptor(_class2.prototype, "loadingNode", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GameControllerEventType.ts", ['cc'], function (exports) {
  var cclegacy;
  return {
    setters: [function (module) {
      cclegacy = module.cclegacy;
    }],
    execute: function () {
      cclegacy._RF.push({}, "cb145hCQUFKNb5altGyzJUY", "GameControllerEventType", undefined);
      /**
       * 全局游戏事件
       */


      var GameControllerEventType = exports('GameControllerEventType', /*#__PURE__*/function (GameControllerEventType) {
        GameControllerEventType[GameControllerEventType["GAME_SUCCESS"] = 0] = "GAME_SUCCESS";
        GameControllerEventType[GameControllerEventType["GAME_FAIL"] = 1] = "GAME_FAIL";
        GameControllerEventType[GameControllerEventType["GAME_NEW"] = 2] = "GAME_NEW";
        GameControllerEventType[GameControllerEventType["ROLE_COINS_UPDATE"] = 3] = "ROLE_COINS_UPDATE";
        return GameControllerEventType;
      }({})); // 角色皮肤变化

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GameControllerScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './GButtonScript.ts', './GlobalData.ts', './LoginBase.ts', './GLabelScoreScript.ts', './GDialogScript.ts', './ResourcesUtils.ts', './MyRoleBag.ts', './Config.ts', './GameControllerEventType.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Node, Prefab, CCInteger, director, instantiate, Component, GButtonScript, GlobalData, GameBaseDataConfig, GLabelScoreScript, GDialogScript, ResourcesUtils, MyRoleBag, Config, GameControllerEventType;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Node = module.Node;
      Prefab = module.Prefab;
      CCInteger = module.CCInteger;
      director = module.director;
      instantiate = module.instantiate;
      Component = module.Component;
    }, function (module) {
      GButtonScript = module.GButtonScript;
    }, function (module) {
      GlobalData = module.GlobalData;
    }, function (module) {
      GameBaseDataConfig = module.GameBaseDataConfig;
    }, function (module) {
      GLabelScoreScript = module.GLabelScoreScript;
    }, function (module) {
      GDialogScript = module.GDialogScript;
    }, function (module) {
      ResourcesUtils = module.ResourcesUtils;
    }, function (module) {
      MyRoleBag = module.MyRoleBag;
    }, function (module) {
      Config = module.Config;
    }, function (module) {
      GameControllerEventType = module.GameControllerEventType;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _class, _class2, _descriptor, _descriptor2, _descriptor3, _descriptor4, _descriptor5, _descriptor6, _descriptor7;

      cclegacy._RF.push({}, "eda3a4JHwxKCYKMegyEPAKc", "GameControllerScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var GameControllerScript = exports('GameControllerScript', (_dec = ccclass('GameControllerScript'), _dec2 = property(Node), _dec3 = property(Node), _dec4 = property(Prefab), _dec5 = property(Node), _dec6 = property(Prefab), _dec7 = property(Node), _dec8 = property(CCInteger), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GameControllerScript, _Component);

        function GameControllerScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this; // UI 关卡信息

          _initializerDefineProperty(_this, "levelValueNode", _descriptor, _assertThisInitialized(_this)); // 返回按钮


          _initializerDefineProperty(_this, "backNode", _descriptor2, _assertThisInitialized(_this)); // 游戏状态弹窗


          _initializerDefineProperty(_this, "gameStatusDialog", _descriptor3, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "uiRootNode", _descriptor4, _assertThisInitialized(_this)); // 通用ui


          _initializerDefineProperty(_this, "toastPrefab", _descriptor5, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "canvasNode", _descriptor6, _assertThisInitialized(_this));
          /**
           * 0： 关闭
           * 1： 成功
           * 2： 失败
           */


          _initializerDefineProperty(_this, "debugGameState", _descriptor7, _assertThisInitialized(_this));

          return _this;
        }

        var _proto = GameControllerScript.prototype;

        _proto.start = function start() {
          var _this2 = this;

          MyRoleBag.initUpdateRoleInfos();
          var currentLevel = GlobalData.getInstance().get(GameBaseDataConfig.getInstance().LEVEL_CURRENT_KEY); // 更新ui

          this.levelValueNode.getComponent(GLabelScoreScript).setScore(currentLevel.levelIndex); // 返回

          this.backNode.getComponent(GButtonScript).setOnClickOption({
            onClick: function onClick(node) {
              // 回首页
              director.loadScene('home');
            }
          }); // 补充游戏逻辑, 测试弹窗

          setTimeout(function () {
            if (_this2.debugGameState === 1) {
              _this2.checkGameStatus(true, true);
            } else if (_this2.debugGameState === 2) {
              _this2.checkGameStatus(true, false);
            }
          }, 1000); // 监听游戏状态

          director.on(GameControllerEventType.GAME_SUCCESS, this.gameSuccess, this);
          director.on(GameControllerEventType.GAME_FAIL, this.gameFail, this);
          director.emit(GameControllerEventType.GAME_NEW);
        };

        _proto.gameFail = function gameFail() {
          this.checkGameStatus(true, false);
        };

        _proto.gameSuccess = function gameSuccess() {
          this.checkGameStatus(true, true); // 通关奖励

          var roleBag = MyRoleBag.get();
          MyRoleBag.addCoin(Config.LEVEL_REWARD, roleBag); // 保存数据

          GlobalData.getInstance().set(GameBaseDataConfig.getInstance().ROLE_BAG_KEY, roleBag);
          ResourcesUtils.saveToPlatform(GameBaseDataConfig.getInstance().ROLE_BAG_PATH, roleBag);
        };

        _proto.checkGameStatus = function checkGameStatus(gameOver, complete) {
          if (complete === void 0) {
            complete = false;
          }

          if (!complete && !gameOver) {
            return;
          }

          var currentLevel = GlobalData.getInstance().get(GameBaseDataConfig.getInstance().LEVEL_CURRENT_KEY);
          var dialogTitle = "LEVEL " + currentLevel.levelIndex;
          var dialogConformTitle = "下一关";
          var dialogContext = "恭喜挑战成功";

          if (complete) {
            // 当前关，设置为已完成
            currentLevel.complete = true; // 找下一关

            var levels = GlobalData.getInstance().get(GameBaseDataConfig.getInstance().LEVEL_DATA_KEY);

            for (var index = 0; index < levels.length; index++) {
              var element = levels[index];

              if (currentLevel.getLevelUid() === element.getLevelUid()) {
                // 更新后保存
                currentLevel.copyLevelResult(element);

                if (index + 1 < levels.length) {
                  var newCurrentLevel = levels[index + 1]; // 相同场景的下一关

                  if (currentLevel.levelScene === newCurrentLevel.levelScene) {
                    // 更新当前关卡
                    GlobalData.getInstance().set(GameBaseDataConfig.getInstance().LEVEL_CURRENT_KEY, newCurrentLevel);
                  }
                }

                break;
              }
            } // 保存进度


            ResourcesUtils.saveToPlatform(GameBaseDataConfig.getInstance().LEVEL_DATA_PATH, levels);
            console.log("save levels to platform!!!");
          } else {
            // 重新开始, gameover
            dialogConformTitle = "重新开始";
            dialogContext = "很遗憾，挑战失败";
          }

          var dialogNode = instantiate(this.gameStatusDialog);
          this.uiRootNode.addChild(dialogNode);
          var dialog = dialogNode.getComponent(GDialogScript);
          dialog.setConformValue(dialogConformTitle);
          dialog.setTitleValue(dialogTitle);
          dialog.setContetValue(dialogContext);
          dialog.show({
            onConform: function onConform() {
              // 重新开始
              director.loadScene('level');
            },
            onCancel: function onCancel() {
              // 回首页
              director.loadScene('home');
            }
          });
        };

        return GameControllerScript;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "levelValueNode", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "backNode", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "gameStatusDialog", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor4 = _applyDecoratedDescriptor(_class2.prototype, "uiRootNode", [_dec5], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor5 = _applyDecoratedDescriptor(_class2.prototype, "toastPrefab", [_dec6], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor6 = _applyDecoratedDescriptor(_class2.prototype, "canvasNode", [_dec7], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor7 = _applyDecoratedDescriptor(_class2.prototype, "debugGameState", [_dec8], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return 0;
        }
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GameLevel.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Node, RigidBody2D, instantiate, Component;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Node = module.Node;
      RigidBody2D = module.RigidBody2D;
      instantiate = module.instantiate;
      Component = module.Component;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _class, _class2, _descriptor, _descriptor2;

      cclegacy._RF.push({}, "e8175uF7TBJub8SPW3qvY+A", "GameLevel", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var GameLevel = exports('GameLevel', (_dec = ccclass('GameLevel'), _dec2 = property(Node), _dec3 = property(Node), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GameLevel, _Component);

        function GameLevel() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "pinHolesNode", _descriptor, _assertThisInitialized(_this));

          _this.layers = [];

          _initializerDefineProperty(_this, "pinsNode", _descriptor2, _assertThisInitialized(_this));

          _this.pinHoles = [];
          _this.pins = [];
          return _this;
        }

        var _proto = GameLevel.prototype;

        _proto.onLoad = function onLoad() {
          for (var index = 0; index < this.node.children.length; index++) {
            var element = this.node.children[index];

            if (element.name.startsWith('layer')) {
              this.layers.push(element);
            }
          }

          this.pinHoles = this.pinHolesNode.children;
          this.pins = this.pinsNode.children;
          this.initLayerCollisionGroup();
        } // 每一层设置不同的group 避免互相碰撞
        ;

        _proto.initLayerCollisionGroup = function initLayerCollisionGroup() {
          var allNode = this.getAllLayerNodes();

          var _loop = function _loop(index) {
            var layerNodes = allNode[index];
            layerNodes.forEach(function (e) {
              // 4, 8, 16, 32, 64
              e.getComponent(RigidBody2D).group = Math.pow(2, index + 2);
            });
          };

          for (var index = 0; index < allNode.length; index++) {
            _loop(index);
          }
        };

        _proto.update = function update(deltaTime) {};

        _proto.emptyLayerNode = function emptyLayerNode() {
          return this.getAllLayerNodes().length === 0;
        };

        _proto.getAllLayerNodes = function getAllLayerNodes() {
          var res = [];

          for (var index = 0; index < this.layers.length; index++) {
            var layerNode = this.layers[index];
            var validNode = layerNode.children.filter(function (e) {
              return e.active;
            });

            if (validNode.length > 0) {
              res.push(validNode);
            }
          }

          return res;
        } // 物体静止之后会停止碰撞检查，如果不唤醒则不会进行碰撞计算
        ;

        _proto.wakeUpLayerNodes = function wakeUpLayerNodes() {
          var allNode = this.getAllLayerNodes();

          for (var index = 0; index < allNode.length; index++) {
            var layerNodes = allNode[index];
            layerNodes.forEach(function (e) {
              if (!e.getComponent(RigidBody2D).isAwake()) {
                e.getComponent(RigidBody2D).wakeUp();
              }
            });
          }
        }
        /**
         * 替换Pin图标
         */
        ;

        _proto.replacePinPrefab = function replacePinPrefab(pinPrefab) {
          for (var index = 0; index < this.pins.length; index++) {
            var element = this.pins[index];
            var newNode = instantiate(pinPrefab);
            this.replaceNode(element, newNode);
          }

          this.pins = this.pinsNode.children;
        };

        _proto.replaceNode = function replaceNode(oldNode, newNode) {
          var parent = oldNode.parent;

          if (parent) {
            var index = parent.children.indexOf(oldNode);

            if (index !== -1) {
              parent.insertChild(newNode, index);
              newNode.position = oldNode.position;
              newNode.rotation = oldNode.rotation;
              newNode.scale = oldNode.scale;
              oldNode.removeFromParent();
            }
          }
        };

        return GameLevel;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "pinHolesNode", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "pinsNode", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GameRoot.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './AudioManager.ts', './GSettingsScript.ts', './GlobalData.ts', './Share.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, AudioSource, assert, director, Component, AudioManager, GSettingsScript, GlobalData, Share;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      AudioSource = module.AudioSource;
      assert = module.assert;
      director = module.director;
      Component = module.Component;
    }, function (module) {
      AudioManager = module.AudioManager;
    }, function (module) {
      GSettingsScript = module.GSettingsScript;
    }, function (module) {
      GlobalData = module.GlobalData;
    }, function (module) {
      Share = module.Share;
    }],
    execute: function () {
      var _dec, _dec2, _class, _class2, _descriptor;

      cclegacy._RF.push({}, "f2b82/uUi9PJoHI/aEPwVV9", "GameRoot", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var GameRoot = exports('GameRoot', (_dec = ccclass('GameRoot'), _dec2 = property(AudioSource), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GameRoot, _Component);

        function GameRoot() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "_audioSource", _descriptor, _assertThisInitialized(_this));

          return _this;
        }

        var _proto = GameRoot.prototype;

        _proto.onLoad = function onLoad() {
          // 允许分享
          Share.showShareMenu();
          var audioSource = this.getComponent(AudioSource);
          assert(audioSource);
          this._audioSource = audioSource; // 避免重复打开背景音乐

          var KEY = "game_root_add_persist_root_node";
          var flag = false;

          if (GlobalData.instance.has(KEY)) {
            flag = GlobalData.instance.get(KEY);
          }

          if (!flag) {
            // 背景音乐使用常驻节点
            director.addPersistRootNode(this.node); // init AudioManager

            AudioManager.instance.init(this._audioSource);
            GlobalData.instance.set(KEY, true); // 检查是否要开启音乐

            GSettingsScript.checkState();
          } else {
            this._audioSource.stop();
          }
        };

        _proto.start = function start() {
          if (typeof cocosAnalytics !== 'undefined') {
            cocosAnalytics.enableDebug(true);
          }
        };

        return GameRoot;
      }(Component), _descriptor = _applyDecoratedDescriptor(_class2.prototype, "_audioSource", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return null;
        }
      }), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GameScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './JobSystem.ts', './GameLevel.ts', './PrefabsUitls.ts', './ResourcesUtils.ts', './DraggableNode.ts', './PinAndHoles.ts', './MyRoleBag.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Prefab, Node, instantiate, Component, JobSystem, GameLevel, PrefabsUtils, ResourcesUtils, DraggableNode, PinAndHoles, MyRoleBag;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Prefab = module.Prefab;
      Node = module.Node;
      instantiate = module.instantiate;
      Component = module.Component;
    }, function (module) {
      JobSystem = module.JobSystem;
    }, function (module) {
      GameLevel = module.GameLevel;
    }, function (module) {
      PrefabsUtils = module.PrefabsUtils;
    }, function (module) {
      ResourcesUtils = module.ResourcesUtils;
    }, function (module) {
      DraggableNode = module.DraggableNode;
    }, function (module) {
      PinAndHoles = module.PinAndHoles;
    }, function (module) {
      MyRoleBag = module.MyRoleBag;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _class, _class2, _descriptor, _descriptor2;

      cclegacy._RF.push({}, "966aeIANgJEvLd3EvyEuGVr", "GameScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var GameScript = exports('default', (_dec = ccclass('GameScript'), _dec2 = property(Prefab), _dec3 = property(Node), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GameScript, _Component);

        function GameScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "pinPrefab", _descriptor, _assertThisInitialized(_this)); // 地面， 如果撞到地面就会吸附


          _initializerDefineProperty(_this, "groundNode", _descriptor2, _assertThisInitialized(_this)); // 游戏进度情况记录


          _this.gameOver = false;
          _this.listener = void 0; // 顺序执行任务

          _this.jobSystem = new JobSystem();
          _this.gameLevel = undefined;
          _this.pinAndHoles = new PinAndHoles();
          _this.checkTimeOffset = 0;
          return _this;
        }

        var _proto = GameScript.prototype;

        _proto.setLevel = function setLevel(level) {
          var _this2 = this;

          var initJobs = new JobSystem();
          var roleSkinPrefab = undefined; // 获取pin

          initJobs.addAsyncJob(function () {
            return new Promise(function (resolve) {
              var rolbag = MyRoleBag.get();
              PrefabsUtils.loadRoleSkinById(rolbag.role.roleSkinId, function (data) {
                if (data) {
                  roleSkinPrefab = data[0];
                }

                resolve();
              });
            });
          }); // 添加level

          initJobs.addAsyncJob(function () {
            return new Promise(function (resolve) {
              // 从level中获取level的prefab
              ResourcesUtils.startLoadPrefab(level.levelPrefab, function (data) {
                var gameLevelNode = instantiate(data);

                _this2.node.addChild(gameLevelNode); // 在addChild完成之后，避免GameLevel没有初始化完成


                _this2.gameLevel = gameLevelNode.getComponent(GameLevel);

                if (roleSkinPrefab) {
                  _this2.gameLevel.replacePinPrefab(roleSkinPrefab);
                }

                _this2.pinAndHoles.init(_this2.gameLevel);

                resolve();
              });
            });
          }); // 注册逻辑

          initJobs.addJob(function () {
            // Pin的移动监听，如果移动失败则返回原地
            _this2.registCheckAfterMovePin();
          });
          initJobs.runJobs();
        };

        _proto.registCheckAfterMovePin = function registCheckAfterMovePin() {
          var _this3 = this;

          var DRAG_SCALE = 2;

          var _loop = function _loop() {
            var element = _this3.gameLevel.pins[index];
            element.getComponent(DraggableNode).setOnDragListener({
              onDragBegin: function onDragBegin(pin) {
                // 开始移动的时候放大
                var scale = pin.getScale().multiplyScalar(DRAG_SCALE);
                pin.setScale(scale);
              },
              onDragEnd: function onDragEnd(pin) {
                // 移动结束时缩小
                var scale = pin.getScale().multiplyScalar(1 / DRAG_SCALE);
                pin.setScale(scale);
                var originPos = element.getComponent(DraggableNode).startPos;

                var flag = _this3.pinAndHoles.attempMovePin(element, originPos);

                if (!flag) {
                  // 移动失败恢复
                  pin.setPosition(originPos);
                } else {
                  // 移动成功激活碰撞
                  _this3.gameLevel.wakeUpLayerNodes();
                }
              }
            });
          };

          for (var index = 0; index < this.gameLevel.pins.length; index++) {
            _loop();
          }
        };

        _proto.onLoad = function onLoad() {// 打开物理调试
          // PhysicsSystem2D.instance.debugDrawFlags = EPhysics2DDrawFlags.All;
        };

        _proto.update = function update(dt) {
          if (this.gameOver) {
            return;
          } // 集中处理任务


          if (!this.jobSystem.empty()) {
            this.jobSystem.runJobs();
          } // 降低检查频次


          this.checkTimeOffset += dt;

          if (this.checkTimeOffset > 2) {
            this.checkTimeOffset = 0;

            if (this.gameLevel.emptyLayerNode()) {
              // game over
              this.gameOver = true;

              if (this.listener) {
                this.listener.onGameSuccess();
              }
            }
          }
        };

        _proto.setGameStateListener = function setGameStateListener(listener) {
          this.listener = listener;
        };

        return GameScript;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "pinPrefab", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return null;
        }
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "groundNode", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return null;
        }
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GButtonRewardVideoScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './GLabelScoreScript.ts', './GButtonScript.ts', './RewardVideo.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Node, CCInteger, GLabelScoreScript, GButtonScript, RewardVideo;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Node = module.Node;
      CCInteger = module.CCInteger;
    }, function (module) {
      GLabelScoreScript = module.GLabelScoreScript;
    }, function (module) {
      GButtonScript = module.GButtonScript;
    }, function (module) {
      RewardVideo = module.RewardVideo;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _class, _class2, _descriptor, _descriptor2, _descriptor3;

      cclegacy._RF.push({}, "73329zH/RJJqrQLcFGbMXFe", "GButtonRewardVideoScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      /**
       * 支持单击，单击放大，单击完成恢复大小
       * 单击后开始播放视频，播放退出或者完成的时候进行返回
       * 为播放完成的时候会弹出提醒
       */

      var GButtonRewardVideoScript = exports('GButtonRewardVideoScript', (_dec = ccclass('GButtonRewardVideoScript'), _dec2 = property(Node), _dec3 = property(Node), _dec4 = property(CCInteger), _dec(_class = (_class2 = /*#__PURE__*/function (_GButtonScript) {
        _inheritsLoose(GButtonRewardVideoScript, _GButtonScript);

        function GButtonRewardVideoScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _GButtonScript.call.apply(_GButtonScript, [this].concat(args)) || this; // video

          _initializerDefineProperty(_this, "videoNode", _descriptor, _assertThisInitialized(_this)); // 左上角数量
          // 分享一次增加的数量


          _initializerDefineProperty(_this, "counterNode", _descriptor2, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "shareAddCounter", _descriptor3, _assertThisInitialized(_this)); // 动画相关


          _this.listener = void 0; // 单击计数

          _this.counter = 0;
          _this.counterEnable = false;
          _this.videoEnable = false;
          return _this;
        }

        var _proto = GButtonRewardVideoScript.prototype;

        _proto.onLoad = function onLoad() {
          var _this2 = this;

          _GButtonScript.prototype.onLoad.call(this);

          _GButtonScript.prototype.setOnClickOption.call(this, {
            onClick: function onClick() {
              _this2.processShare();
            }
          }); // 计数 share


          this.videoEnable = this.videoNode && this.videoNode.active;
          this.counterEnable = this.counterNode && this.counterNode.active;

          if (this.counterEnable) {
            this.counter = this.counterNode.getComponent(GLabelScoreScript).getScore();
          }
        };

        _proto.setOnRVClickOption = function setOnRVClickOption(opt) {
          this.listener = opt;
        } // 处理计数
        ;

        _proto.processCounter = function processCounter() {
          this.counter--;
          this.counterNode.getComponent(GLabelScoreScript).setScore(this.counter);
        } // 发起分享, 成功或者失败 会通过clickOption回调
        ;

        _proto.processShare = function processShare() {
          var _this3 = this;

          if (this.counterEnable) {
            this.processCounter();

            if (this.counter >= 0) {
              // 有次数的时候不需要分享
              // 返回分享成功，用次数抵消分享次数
              if (this.listener.onVideoPlayFinish) {
                this.listener.onVideoPlayFinish(true);
              }

              return;
            }
          }

          if (this.videoEnable) {
            new RewardVideo().show(function (complete) {
              console.log("[game][rewardvideo] show result ", complete);

              if (complete && _this3.counterEnable) {
                // 完成增加数量
                _this3.counter += _this3.shareAddCounter;

                _this3.counterNode.getComponent(GLabelScoreScript).setScore(_this3.counter);
              }

              if (_this3.listener.onVideoPlayFinish) {
                _this3.listener.onVideoPlayFinish(complete);
              }
            });
          }
        };

        return GButtonRewardVideoScript;
      }(GButtonScript), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "videoNode", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "counterNode", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "shareAddCounter", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return 3;
        }
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GButtonScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, CCFloat, Node, Input, tween, Label, UITransform, Sprite, Component;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      CCFloat = module.CCFloat;
      Node = module.Node;
      Input = module.Input;
      tween = module.tween;
      Label = module.Label;
      UITransform = module.UITransform;
      Sprite = module.Sprite;
      Component = module.Component;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _dec5, _class, _class2, _descriptor, _descriptor2, _descriptor3, _descriptor4;

      cclegacy._RF.push({}, "22754yBNkhKyqAy6o+1PVGP", "GButtonScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      /**
       * 支持单击，单击放大，单击完成恢复大小
       */

      var GButtonScript = exports('GButtonScript', (_dec = ccclass('GButtonScript'), _dec2 = property(CCFloat), _dec3 = property(CCFloat), _dec4 = property(Node), _dec5 = property(Node), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GButtonScript, _Component);

        function GButtonScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "clickAnimateDuration", _descriptor, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "clickBiggerScale", _descriptor2, _assertThisInitialized(_this)); // 状态


          _initializerDefineProperty(_this, "selectedNode", _descriptor3, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "lockNode", _descriptor4, _assertThisInitialized(_this)); // 动画相关


          _this.clickOption = void 0;
          _this.defaultScale = void 0;
          _this.biggerScale = void 0; // 状态

          _this.selected = false;
          _this.locked = false;
          _this.touchingID = 0;
          return _this;
        }

        var _proto = GButtonScript.prototype;

        _proto.onLoad = function onLoad() {
          this.defaultScale = this.node.getScale();
          this.biggerScale = this.defaultScale.clone().multiplyScalar(this.clickBiggerScale);
          this.node.on(Input.EventType.TOUCH_START, this.onTouch, this);
          this.node.on(Input.EventType.TOUCH_END, this.onTouch, this);
          this.node.on(Input.EventType.TOUCH_CANCEL, this.onTouch, this);
        };

        _proto.update = function update(deltaTime) {};

        _proto.setOnClickOption = function setOnClickOption(opt) {
          this.clickOption = opt;
        };

        _proto.onTouch = function onTouch(evt) {
          var touch = evt.touch;
          var tid = touch.getID();
          var touchingID = this.touchingID;

          if (evt.type === Node.EventType.TOUCH_START) {
            this.scaleAnimate(true); // 开始触摸

            if (touchingID) {
              return;
            }

            this.touchingID = tid;
          } else {
            // 就算不是单击也要进行恢复
            this.scaleAnimate(false); // 结束触摸

            if (touchingID && touchingID !== tid) return; // 不是正触摸的点，忽略之
            // 得到滑动向量

            var vec = touch.getLocation().subtract(touch.getStartLocation());

            if (vec.lengthSqr() < 10) {
              // 滑动距离不多，可认为是点击
              if (this.clickOption) {
                if (this.clickOption.onClick) {
                  this.clickOption.onClick(this.node);
                }
              }
            }

            this.touchingID = 0;
          }
        };

        _proto.scaleAnimate = function scaleAnimate(toBigger) {
          var scale = toBigger ? this.biggerScale : this.defaultScale;
          tween(this.node).to(this.clickAnimateDuration, {
            scale: scale
          }).start();
        };

        _proto.setName = function setName(v) {
          this.node.getChildByName('name').getComponent(Label).string = v;
        };

        _proto.setNameColor = function setNameColor(c) {
          this.node.getChildByName('name').getComponent(Label).color = c;
        };

        _proto.setContentSize = function setContentSize(size) {
          this.node.getComponent(UITransform).contentSize = size;
        };

        _proto.setBackgroundColor = function setBackgroundColor(c) {
          this.node.getComponent(Sprite).color = c;
        } // 设置选中
        ;

        _proto.setSelectd = function setSelectd(flag) {
          this.selected = flag;
          this.selectedNode.active = flag;
        };

        _proto.setLocked = function setLocked(flag) {
          this.locked = flag;
          this.lockNode.active = flag;
        };

        return GButtonScript;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "clickAnimateDuration", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return 0.3;
        }
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "clickBiggerScale", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return 2;
        }
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "selectedNode", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor4 = _applyDecoratedDescriptor(_class2.prototype, "lockNode", [_dec5], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GButtonSettingsScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './GButtonScript.ts', './GDialogScript.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Node, Component, GButtonScript, GDialogScript;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Node = module.Node;
      Component = module.Component;
    }, function (module) {
      GButtonScript = module.GButtonScript;
    }, function (module) {
      GDialogScript = module.GDialogScript;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _class, _class2, _descriptor, _descriptor2;

      cclegacy._RF.push({}, "21207Og5gVHBIHko2Cl7MwW", "GButtonSettingsScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      /**
       * 需要挂到GButton上
       * 单击后弹出设置页面
       */

      var GButtonSettingsScript = exports('GButtonSettingsScript', (_dec = ccclass('GButtonSettingsScript'), _dec2 = property(Node), _dec3 = property(Node), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GButtonSettingsScript, _Component);

        function GButtonSettingsScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "settingsNode", _descriptor, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "settingsDialogNode", _descriptor2, _assertThisInitialized(_this));

          _this.isShowDialog = false;
          return _this;
        }

        var _proto = GButtonSettingsScript.prototype;

        _proto.onLoad = function onLoad() {
          var _this2 = this; // 菜单


          this.settingsNode.getComponent(GButtonScript).setOnClickOption({
            onClick: function onClick(node) {
              if (_this2.isShowDialog) {
                _this2.isShowDialog = false;

                _this2.settingsDialogNode.getComponent(GDialogScript).hide();

                return;
              }

              _this2.isShowDialog = true; // 不会移除，会复用

              _this2.settingsDialogNode.getComponent(GDialogScript).autoRemove = false;

              _this2.settingsDialogNode.getComponent(GDialogScript).show({
                onConform: function onConform() {
                  _this2.isShowDialog = false;
                },
                onCancel: function onCancel() {
                  _this2.isShowDialog = false;
                }
              });
            }
          });
        };

        _proto.update = function update(deltaTime) {};

        return GButtonSettingsScript;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "settingsNode", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "settingsDialogNode", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GButtonShareScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './Share.ts', './GLabelScoreScript.ts', './GButtonScript.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Node, CCFloat, Share, GLabelScoreScript, GButtonScript;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Node = module.Node;
      CCFloat = module.CCFloat;
    }, function (module) {
      Share = module.Share;
    }, function (module) {
      GLabelScoreScript = module.GLabelScoreScript;
    }, function (module) {
      GButtonScript = module.GButtonScript;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _class, _class2, _descriptor, _descriptor2, _descriptor3;

      cclegacy._RF.push({}, "d80edcXWHVOSrHSfVU6qbVw", "GButtonShareScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      /**
       * 支持单击，单击放大，单击完成恢复大小
       * 如果Share是开启的，则单击后会跳转分享
       * 如果数量为0则单击的时候会进行分享，
       */

      var GButtonShareScript = exports('GButtonShareScript', (_dec = ccclass('GButtonShareScript'), _dec2 = property(Node), _dec3 = property(Node), _dec4 = property(CCFloat), _dec(_class = (_class2 = /*#__PURE__*/function (_GButtonScript) {
        _inheritsLoose(GButtonShareScript, _GButtonScript);

        function GButtonShareScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _GButtonScript.call.apply(_GButtonScript, [this].concat(args)) || this; // 分享

          _initializerDefineProperty(_this, "shareNode", _descriptor, _assertThisInitialized(_this)); // 左上角数量
          // 分享一次增加的数量


          _initializerDefineProperty(_this, "counterNode", _descriptor2, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "shareAddCounter", _descriptor3, _assertThisInitialized(_this)); // 动画相关


          _this.clickShareOption = void 0; // 单击计数

          _this.counter = 0;
          _this.counterEnable = false;
          _this.shareEnable = false;
          return _this;
        }

        var _proto = GButtonShareScript.prototype;

        _proto.onLoad = function onLoad() {
          var _this2 = this;

          _GButtonScript.prototype.onLoad.call(this);

          _GButtonScript.prototype.setOnClickOption.call(this, {
            onClick: function onClick() {
              _this2.processShare();
            }
          }); // 计数 share


          this.shareEnable = this.shareNode.active;
          this.counterEnable = this.counterNode.active;

          if (this.counterEnable) {
            this.counter = this.counterNode.getComponent(GLabelScoreScript).getScore();
          }
        };

        _proto.setOnClickOption = function setOnClickOption(opt) {
          this.clickShareOption = opt;
        } // 处理计数
        ;

        _proto.processCounter = function processCounter() {
          this.counter--;
          this.counterNode.getComponent(GLabelScoreScript).setScore(this.counter);
        } // 发起分享, 成功或者失败 会通过clickOption回调
        ;

        _proto.processShare = function processShare() {
          var _this3 = this;

          if (this.counterEnable) {
            this.processCounter();

            if (this.counter >= 0) {
              // 有次数的时候不需要分享
              // 返回分享成功，用次数抵消分享次数
              if (this.clickShareOption.onShareComplete) {
                this.clickShareOption.onShareComplete(true);
              }

              return;
            }
          }

          if (this.shareEnable) {
            var message = this.clickShareOption && this.clickShareOption.getShareMessage ? this.clickShareOption.getShareMessage() : "";
            new Share().shareMessage(message, function (flag) {
              if (flag) {
                // 分享完成增加数量
                _this3.counter += _this3.shareAddCounter;

                _this3.counterNode.getComponent(GLabelScoreScript).setScore(_this3.counter);
              }

              if (_this3.clickShareOption.onShareComplete) {
                _this3.clickShareOption.onShareComplete(flag);
              }
            });
          }
        };

        return GButtonShareScript;
      }(GButtonScript), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "shareNode", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "counterNode", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "shareAddCounter", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return 3;
        }
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GDialogGridViewScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './GGridViewScript.ts', './GDialogScript.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Node, CCBoolean, Component, GGridViewScript, GDialogScript;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Node = module.Node;
      CCBoolean = module.CCBoolean;
      Component = module.Component;
    }, function (module) {
      GGridViewScript = module.GGridViewScript;
    }, function (module) {
      GDialogScript = module.GDialogScript;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _class, _class2, _descriptor, _descriptor2, _descriptor3;

      cclegacy._RF.push({}, "8c0cdckD9NESKqxg7TZPxkX", "GDialogGridViewScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var GDialogGridViewScript = exports('GDialogGridViewScript', (_dec = ccclass('GDialogGridViewScript'), _dec2 = property(Node), _dec3 = property(Node), _dec4 = property(CCBoolean), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GDialogGridViewScript, _Component);

        function GDialogGridViewScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "dialogNode", _descriptor, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "gridViewNode", _descriptor2, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "autoRemove", _descriptor3, _assertThisInitialized(_this));

          return _this;
        }

        var _proto = GDialogGridViewScript.prototype;

        _proto.update = function update(deltaTime) {};

        _proto.setDataAdapter = function setDataAdapter(opt) {
          this.gridViewNode.getComponent(GGridViewScript).setDataAdapter(opt);
        };

        _proto.show = function show(onCancelCallback) {
          var _this2 = this;

          this.dialogNode.getComponent(GDialogScript).show({
            onCancel: function onCancel() {
              if (onCancelCallback) {
                onCancelCallback();
              }

              if (_this2.autoRemove) {
                _this2.node.removeFromParent();
              }
            }
          });
        };

        _proto.setTitleValue = function setTitleValue(v) {
          this.dialogNode.getComponent(GDialogScript).setTitleValue(v);
        };

        return GDialogGridViewScript;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "dialogNode", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "gridViewNode", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "autoRemove", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return true;
        }
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GDialogScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './GButtonScript.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, CCBoolean, CCFloat, Node, Vec3, tween, Label, Component, GButtonScript;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      CCBoolean = module.CCBoolean;
      CCFloat = module.CCFloat;
      Node = module.Node;
      Vec3 = module.Vec3;
      tween = module.tween;
      Label = module.Label;
      Component = module.Component;
    }, function (module) {
      GButtonScript = module.GButtonScript;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _class, _class2, _descriptor, _descriptor2, _descriptor3, _descriptor4, _descriptor5;

      cclegacy._RF.push({}, "eb6b3t1HEpOPKJVeW/lDDX6", "GDialogScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      /**
       * 默认为显示，建议默认设置active = false
       */

      var GDialogScript = exports('GDialogScript', (_dec = ccclass('GDialogScript'), _dec2 = property(CCBoolean), _dec3 = property(CCFloat), _dec4 = property(Node), _dec5 = property(Node), _dec6 = property(CCBoolean), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GDialogScript, _Component);

        function GDialogScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "debug", _descriptor, _assertThisInitialized(_this)); // 弹窗动画时长


          _initializerDefineProperty(_this, "durationshowOrHide", _descriptor2, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "conformNode", _descriptor3, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "cancelNode", _descriptor4, _assertThisInitialized(_this)); // 确认和取消后自动删除


          _initializerDefineProperty(_this, "autoRemove", _descriptor5, _assertThisInitialized(_this)); // 动画


          _this.defaultScale = void 0;
          _this.minScale = new Vec3(0.1, 0.1, 0);
          _this.dialogOpt = void 0;
          return _this;
        }

        var _proto = GDialogScript.prototype;

        _proto.onLoad = function onLoad() {
          var _this2 = this;

          this.defaultScale = this.node.getScale(); // 事件

          this.conformNode.getComponent(GButtonScript).setOnClickOption({
            onClick: function onClick(node) {
              if (_this2.dialogOpt && _this2.dialogOpt.onConform) {
                _this2.dialogOpt.onConform();
              }

              if (_this2.autoRemove) {
                _this2.remove();
              } else {
                _this2.hide();
              }
            }
          });
          this.cancelNode.getComponent(GButtonScript).setOnClickOption({
            onClick: function onClick(node) {
              if (_this2.dialogOpt && _this2.dialogOpt.onCancel) {
                _this2.dialogOpt.onCancel();
              }

              if (_this2.autoRemove) {
                _this2.remove();
              } else {
                _this2.hide();
              }
            }
          });

          if (this.debug) {
            this.show();
          }
        };

        _proto.update = function update(deltaTime) {}
        /**
         * 显示弹出
         * @param opt 
         */
        ;

        _proto.show = function show(opt) {
          this.dialogOpt = opt;
          this.node.active = true; // 默认设置到很小

          this.node.setScale(this.minScale);
          var newScale = this.defaultScale.clone().multiplyScalar(1.2); // 展示的时候动画弹出

          tween(this.node).to(this.durationshowOrHide - 0.1, {
            scale: newScale
          }).to(0.1, {
            scale: this.defaultScale
          }).call(function () {}).start();
        };

        _proto.hide = function hide() {
          var _this3 = this;

          tween(this.node).to(this.durationshowOrHide, {
            scale: this.minScale
          }).call(function () {
            _this3.node.active = false;
          }).start();
        };

        _proto.remove = function remove() {
          var _this4 = this;

          tween(this.node).to(this.durationshowOrHide, {
            scale: this.minScale
          }).call(function () {
            _this4.node.active = false;

            _this4.node.removeFromParent();
          }).start();
        };

        _proto.setConformValue = function setConformValue(v) {
          this.conformNode.getChildByName('name').getComponent(Label).string = v;
        };

        _proto.setTitleValue = function setTitleValue(v) {
          this.node.getChildByName('title').getComponent(Label).string = v;
        };

        _proto.setContetValue = function setContetValue(v) {
          this.node.getChildByName('context').getComponent(Label).string = v;
        };

        return GDialogScript;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "debug", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return false;
        }
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "durationshowOrHide", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return 0.2;
        }
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "conformNode", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor4 = _applyDecoratedDescriptor(_class2.prototype, "cancelNode", [_dec5], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor5 = _applyDecoratedDescriptor(_class2.prototype, "autoRemove", [_dec6], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return true;
        }
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GGridViewScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Node, Vec4, UITransform, Vec2, Vec3, Component;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Node = module.Node;
      Vec4 = module.Vec4;
      UITransform = module.UITransform;
      Vec2 = module.Vec2;
      Vec3 = module.Vec3;
      Component = module.Component;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _class, _class2, _descriptor, _descriptor2, _descriptor3;

      cclegacy._RF.push({}, "c9ad8lbatZP378em8FsGSpf", "GGridViewScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      /**
       * 选中响应
       */

      /**
       * 利用网格显示内容,每个内容的大小需要一致
       * 每个Item 默认使用锚点 （0.5，0.5）
       * 支持单击回调
       */

      var GGridViewScript = exports('GGridViewScript', (_dec = ccclass('GGridViewScript'), _dec2 = property(Node), _dec3 = property(Node), _dec4 = property(Vec4), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GGridViewScript, _Component);

        function GGridViewScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "contentNode", _descriptor, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "viewNode", _descriptor2, _assertThisInitialized(_this)); // left bottom right top


          _initializerDefineProperty(_this, "marginItem", _descriptor3, _assertThisInitialized(_this)); // 展示数据的内容


          _this.adapter = void 0; // content的大小

          _this.contentSize = void 0;
          _this.isNeedUpdate = false;
          return _this;
        }

        var _proto = GGridViewScript.prototype;

        _proto.onLoad = function onLoad() {
          this.contentSize = this.contentNode.getComponent(UITransform).contentSize;
        };

        _proto.update = function update(deltaTime) {
          if (this.isNeedUpdate) {
            this.updateItems();
            this.isNeedUpdate = false;
          }
        }
        /**
         * 调用的时候会更新页面
         * @param opt 
         */
        ;

        _proto.setDataAdapter = function setDataAdapter(opt) {
          this.adapter = opt;
          this.isNeedUpdate = true;
        };

        _proto.updateItems = function updateItems() {
          if (this.adapter === null) {
            return;
          } // 移除所有


          this.contentNode.removeAllChildren(); // 开始布局

          var totalCount = this.adapter.getCount();

          if (totalCount <= 0) {
            return;
          } // contentNode的 锚点是 0， 1， 左上角是原点


          var firstNode = this.adapter.getNode(0, this.contentNode);
          var itemSize = firstNode.getComponent(UITransform).contentSize.clone(); // 加上margin

          itemSize.x = itemSize.x + this.marginItem.x + this.marginItem.z;
          itemSize.y = itemSize.y + this.marginItem.y + this.marginItem.w; // 水平方向最大数量

          var maxHCounter = Math.floor(this.contentSize.x / itemSize.x); // y轴向下为正方向

          var startPos = new Vec2(itemSize.x / 2, -itemSize.y / 2);

          for (var index = 0; index < totalCount; index++) {
            var x = startPos.x + index % maxHCounter * itemSize.x; // y轴向下为正方向

            var y = startPos.y - Math.floor(index / maxHCounter) * itemSize.y;
            var node = this.adapter.getNode(index, this.contentNode);
            node.setPosition(new Vec3(x, y, 0));
            this.contentNode.addChild(node);
          }
        };

        _proto.setContentSize = function setContentSize(size) {
          // 背景
          this.node.getChildByName("ScrollView").getComponent(UITransform).contentSize = size; // content

          this.viewNode.getComponent(UITransform).contentSize = size;
          this.contentNode.getComponent(UITransform).contentSize = size; // 位置设置到左上角

          this.contentNode.setPosition(new Vec3(-size.x / 2, size.y, 0));
        };

        return GGridViewScript;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "contentNode", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "viewNode", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "marginItem", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return new Vec4(10, 10, 10, 10);
        }
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GLabelCounterTimerScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, CCFloat, Label, Component;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      CCFloat = module.CCFloat;
      Label = module.Label;
      Component = module.Component;
    }],
    execute: function () {
      var _dec, _dec2, _class, _class2, _descriptor;

      cclegacy._RF.push({}, "e4c0awSlfFNXLo70EqC67/G", "GLabelCounterTimerScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var GLabelCounterTimerScript = exports('GLabelCounterTimerScript', (_dec = ccclass('GLabelCounterTimerScript'), _dec2 = property(CCFloat), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GLabelCounterTimerScript, _Component);

        function GLabelCounterTimerScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "totalTime", _descriptor, _assertThisInitialized(_this)); // 总倒计时时间，单位：秒


          _this.currentTime = 0;
          _this.label = void 0;
          _this.updateInterval = 1; // 更新间隔时间，单位：秒

          _this.timer = 0; // 计时器
          // 是否暂停

          _this.isPause = false;
          _this.onCountdownEnd = undefined;
          return _this;
        }

        var _proto = GLabelCounterTimerScript.prototype; // 倒计时结束回调函数

        _proto.start = function start() {
          this.label = this.getComponent(Label);
        };

        _proto.update = function update(dt) {
          if (this.isPause) {
            return;
          }

          this.timer += dt;

          if (this.timer >= this.updateInterval) {
            this.updateTimer();
          }
        };

        _proto.updateTimer = function updateTimer() {
          this.currentTime += Math.floor(this.timer / this.updateInterval);
          this.timer %= this.updateInterval;
          var remainingTime = Math.max(this.totalTime - this.currentTime, 0);
          var hours = Math.floor(remainingTime / 3600);
          var minutes = Math.floor(remainingTime % 3600 / 60);
          var seconds = remainingTime % 60;
          var formattedTime = this.formatTime(hours) + ":" + this.formatTime(minutes) + ":" + this.formatTime(seconds);
          this.label.string = formattedTime;

          if (remainingTime <= 0) {
            // 倒计时结束，停止更新
            this.enabled = false;

            if (this.onCountdownEnd && typeof this.onCountdownEnd === 'function') {
              this.onCountdownEnd(); // 调用倒计时结束回调函数
            }
          }
        };

        _proto.formatTime = function formatTime(value) {
          return value < 10 ? "0" + value : value.toString();
        } // 单位秒
        ;

        _proto.setTotalTime = function setTotalTime(time) {
          this.totalTime = time;

          if (!this.enabled) {
            this.enabled = true;
          }
        } // 单位秒
        ;

        _proto.addTotalTime = function addTotalTime(time) {
          this.setTotalTime(this.totalTime + time);
        };

        _proto.setCountdownEndCallback = function setCountdownEndCallback(callback) {
          this.onCountdownEnd = callback;
        };

        _proto.pause = function pause() {
          this.isPause = true;
        };

        _proto.resume = function resume() {
          this.isPause = false;
        };

        return GLabelCounterTimerScript;
      }(Component), _descriptor = _applyDecoratedDescriptor(_class2.prototype, "totalTime", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return 60;
        }
      }), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GLabelScoreScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Node, CCBoolean, CCInteger, CCFloat, Label, tween, Component;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Node = module.Node;
      CCBoolean = module.CCBoolean;
      CCInteger = module.CCInteger;
      CCFloat = module.CCFloat;
      Label = module.Label;
      tween = module.tween;
      Component = module.Component;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _class, _class2, _descriptor, _descriptor2, _descriptor3, _descriptor4, _descriptor5;

      cclegacy._RF.push({}, "4ea015BXhBDo5WRG3L/dD/b", "GLabelScoreScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      /**
       * 只支持整数
       */

      var GLabelScoreScript = exports('GLabelScoreScript', (_dec = ccclass('GLabelScoreScript'), _dec2 = property(Node), _dec3 = property(CCBoolean), _dec4 = property(CCInteger), _dec5 = property(CCFloat), _dec6 = property(CCFloat), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GLabelScoreScript, _Component);

        function GLabelScoreScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "valueNode", _descriptor, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "debug", _descriptor2, _assertThisInitialized(_this));
          /**
           * 单位秒， 多长时间内完成
           */


          _initializerDefineProperty(_this, "changeTime", _descriptor3, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "changeAnimateDuration", _descriptor4, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "changeBiggerScale", _descriptor5, _assertThisInitialized(_this));

          _this.currentScore = 0;
          _this.targetScore = 0;
          _this.isChaging = false;
          _this.offsetScore = 0;
          _this.lastChangeGapTime = 0; // 动画

          _this.defaultScale = void 0;
          _this.biggerScale = void 0; // 回调

          _this.opt = void 0;
          return _this;
        }

        var _proto = GLabelScoreScript.prototype;

        _proto.onLoad = function onLoad() {
          this.currentScore = this.getScoreFormNode();
          this.targetScore = this.currentScore;
          this.defaultScale = this.node.getScale();
          this.biggerScale = this.defaultScale.clone().multiplyScalar(this.changeBiggerScale);

          if (this.debug) {
            this.setScore(100);
          }
        };

        _proto.update = function update(deltaTime) {
          // 加上之后会让变化变慢
          // this.lastChangeGapTime += deltaTime;
          // if (this.lastChangeGapTime < this.changeAnimateDuration) {
          //     // 避免一直检查
          //     return;
          // }
          // this.lastChangeGapTime = 0;
          if (!this.changeComplete()) {
            if (!this.isChaging) {
              // 保证每次变化一致
              this.isChaging = true;
              this.offsetScore = this.targetScore - this.currentScore;
            }

            this.currentScore += this.changeTime * deltaTime * this.offsetScore;
            this.updateScoreToNode(this.currentScore);
          } else {
            if (this.isChaging) {
              this.isChaging = false;
              this.offsetScore = 0;
              this.currentScore = this.targetScore;
              this.updateScoreToNode(this.targetScore);

              if (this.opt) {
                this.opt.onComplete(this.targetScore);
              }
            }
          }
        };

        _proto.changeComplete = function changeComplete() {
          var offset = Math.abs(this.targetScore - this.currentScore);

          if (offset > 0.01) {
            // 检查避免变化过头了
            if (this.isChaging) {
              if (this.offsetScore < 0) {
                // 逐渐减小，减到比目标值更小的时候就停止
                return this.targetScore - this.currentScore > 0;
              } else {
                return this.targetScore - this.currentScore < 0;
              }
            } else {
              return false;
            }
          }

          return true;
        };

        _proto.getScoreFormNode = function getScoreFormNode() {
          return Number.parseFloat(this.valueNode.getComponent(Label).string);
        };

        _proto.updateScoreToNode = function updateScoreToNode(score) {
          var _this2 = this;

          var intScore = Math.round(score);
          var curScore = this.getScoreFormNode();

          if (curScore !== intScore) {
            // 动画更新
            tween(this.valueNode).to(this.changeAnimateDuration / 2, {
              scale: this.biggerScale
            }).call(function () {
              _this2.valueNode.getComponent(Label).string = JSON.stringify(intScore);

              if (_this2.opt) {
                _this2.opt.onChange(intScore - curScore);
              }
            }).to(this.changeAnimateDuration / 2, {
              scale: this.defaultScale
            }).start();
          }
        }
        /**
         * 设置分数
         */
        ;

        _proto.setScore = function setScore(score, noAnim) {
          if (noAnim === void 0) {
            noAnim = false;
          }

          if (noAnim) {
            this.valueNode.getComponent(Label).string = JSON.stringify(score);
          } else {
            this.targetScore = score;
          }
        };

        _proto.setScoreChangeListener = function setScoreChangeListener(opt) {
          this.opt = opt;
        };

        _proto.getScore = function getScore() {
          return this.currentScore;
        };

        _proto.setColor = function setColor(color) {
          this.valueNode.getComponent(Label).color = color;
        };

        return GLabelScoreScript;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "valueNode", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "debug", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return false;
        }
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "changeTime", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return 2;
        }
      }), _descriptor4 = _applyDecoratedDescriptor(_class2.prototype, "changeAnimateDuration", [_dec5], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return 0.03;
        }
      }), _descriptor5 = _applyDecoratedDescriptor(_class2.prototype, "changeBiggerScale", [_dec6], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return 2;
        }
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GLoadingScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './updateValueLabel.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Label, CCBoolean, Vec3, Component, updateValueLabel;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Label = module.Label;
      CCBoolean = module.CCBoolean;
      Vec3 = module.Vec3;
      Component = module.Component;
    }, function (module) {
      updateValueLabel = module.updateValueLabel;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _class, _class2, _descriptor, _descriptor2, _descriptor3;

      cclegacy._RF.push({}, "7f7d07lrJVMpKqZEyYe/7If", "GLoadingScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var GLoadingScript = exports('GLoadingScript', (_dec = ccclass('GLoadingScript'), _dec2 = property(updateValueLabel), _dec3 = property(Label), _dec4 = property(CCBoolean), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GLoadingScript, _Component);

        function GLoadingScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "lbProgress", _descriptor, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "lbTips", _descriptor2, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "debug", _descriptor3, _assertThisInitialized(_this));

          _this.targetProgress = 0;
          _this.oriPos = new Vec3();
          return _this;
        }

        var _proto = GLoadingScript.prototype;

        _proto.start = function start() {
          var _this2 = this;

          this.show(0);

          if (this.debug) {
            setTimeout(function () {
              _this2.updateProgress(100, "正在加载中...");
            }, 1);
          }
        };

        _proto.show = function show(start) {
          if (start) {
            this.targetProgress = start;
          } else {
            this.targetProgress = 0;
          }

          this.lbProgress.playUpdateValue(this.targetProgress, this.targetProgress, 0);
          this.lbProgress.isPlaying = false;
          this.lbTips.string = '';
          this.oriPos.set(this.lbProgress.node.position);
        };

        _proto.updateProgress = function updateProgress(progress, tips) {
          this.targetProgress = progress;
          var curProgress = Number(this.lbProgress.label.string); //当前进度

          this.lbProgress.playUpdateValue(curProgress, this.targetProgress, (this.targetProgress - curProgress) / 20);

          if (tips) {
            this.lbTips.string = tips;
          }

          if (this.oriPos) {
            this.lbProgress.node.setPosition(new Vec3(this.oriPos.x - 10, this.oriPos.y, this.oriPos.z));
          }
        } // update (deltaTime: number) {
        //     // Your update function goes here.
        // }
        ;

        return GLoadingScript;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "lbProgress", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return null;
        }
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "lbTips", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return null;
        }
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "debug", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return false;
        }
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GlobalData.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './ResourcesUtils.ts'], function (exports) {
  var _inheritsLoose, _createClass, _wrapNativeSuper, cclegacy, _decorator, ResourcesUtils;

  return {
    setters: [function (module) {
      _inheritsLoose = module.inheritsLoose;
      _createClass = module.createClass;
      _wrapNativeSuper = module.wrapNativeSuper;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
    }, function (module) {
      ResourcesUtils = module.ResourcesUtils;
    }],
    execute: function () {
      var _dec, _class, _class2;

      cclegacy._RF.push({}, "a154eHh8PJFbbhiVWB0YAog", "GlobalData", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var GlobalData = exports('GlobalData', (_dec = ccclass('GlobalData'), _dec(_class = (_class2 = /*#__PURE__*/function (_Map) {
        _inheritsLoose(GlobalData, _Map);

        function GlobalData() {
          var _this;

          _this = _Map.call(this) || this;
          _this.jsonData = null;
          _this.path = null;
          _this.KEY_CONFIG = 'MyConfig';
          _this.markSave = false;
          _this.jsonData = {
            "userId": ""
          };
          _this.path = _this.getConfigPath();
          return _this;
        }

        var _proto = GlobalData.prototype;

        _proto.getConfigPath = function getConfigPath() {
          var path = "src/conf";
          return path;
        };

        GlobalData.getInstance = function getInstance() {
          return GlobalData.instance;
        };
        /**
         * 添加全局数据，如果标识重复，则会返回失败
         * @param key 数据标识，不能重复
         */


        _proto.addData = function addData(key, data) {
          if (this.has(key)) {
            return false;
          }

          this.set(key, data);
          return true;
        };

        _proto.setDataStr = function setDataStr(key, data) {
          this.set(key, JSON.stringify(data));
        };

        _proto.getDataStr = function getDataStr(key) {
          return JSON.parse(this.get(key));
        } // 设置后会进行缓存
        ;

        _proto.setGlobalStorgeData = function setGlobalStorgeData(key, value) {
          this.jsonData[key] = value;
          this.save();
        };

        _proto.getGlobalStorgeData = function getGlobalStorgeData(key) {
          return this.jsonData[key];
        };

        _proto.save = function save() {
          // 写入文件
          var str = JSON.stringify(this.jsonData);
          ResourcesUtils.saveToPlatform(this.path, str);
          this.markSave = false;
        };

        _createClass(GlobalData, null, [{
          key: "instance",
          get: function get() {
            if (this._instance) {
              return this._instance;
            }

            this._instance = new GlobalData();
            return this._instance;
          }
        }]);

        return GlobalData;
      }( /*#__PURE__*/_wrapNativeSuper(Map)), _class2._instance = undefined, _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GMainUIRoleAndStoreScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './GlobalData.ts', './LoginBase.ts', './GTabCardScript.ts', './GButtonScript.ts', './MyRoleBag.ts', './ResourcesUtils.ts', './MyLevel.ts', './PrefabsUitls.ts', './JobSystem.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Node, instantiate, director, Component, Color, GlobalData, GameBaseDataConfig, GTabCardScript, GButtonScript, MyRoleBag, ResourcesUtils, MyLevelUtils, PrefabsUtils, JobSystem;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Node = module.Node;
      instantiate = module.instantiate;
      director = module.director;
      Component = module.Component;
      Color = module.Color;
    }, function (module) {
      GlobalData = module.GlobalData;
    }, function (module) {
      GameBaseDataConfig = module.GameBaseDataConfig;
    }, function (module) {
      GTabCardScript = module.GTabCardScript;
    }, function (module) {
      GButtonScript = module.GButtonScript;
    }, function (module) {
      MyRoleBag = module.MyRoleBag;
    }, function (module) {
      ResourcesUtils = module.ResourcesUtils;
    }, function (module) {
      MyLevelUtils = module.MyLevelUtils;
    }, function (module) {
      PrefabsUtils = module.PrefabsUtils;
    }, function (module) {
      JobSystem = module.JobSystem;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _class, _class2, _descriptor, _descriptor2, _descriptor3, _descriptor4, _descriptor5, _descriptor6;

      cclegacy._RF.push({}, "fc750xHMApDAb9rrNmAF2TZ", "GMainUIRoleAndStoreScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property; // tab 显示的内容

      var TAB_INDEX = /*#__PURE__*/function (TAB_INDEX) {
        TAB_INDEX[TAB_INDEX["ROLE_SKIN"] = 0] = "ROLE_SKIN";
        return TAB_INDEX;
      }(TAB_INDEX || {});

      var GMainUIRoleAndStoreScript = exports('GMainUIRoleAndStoreScript', (_dec = ccclass('GMainUIRoleAndStoreScript'), _dec2 = property(Node), _dec3 = property(Node), _dec4 = property(Node), _dec5 = property(Node), _dec6 = property(Node), _dec7 = property(GButtonScript), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GMainUIRoleAndStoreScript, _Component);

        function GMainUIRoleAndStoreScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "roleShowerNode", _descriptor, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "roleShowerSkinNode", _descriptor2, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "roleShowerWeaponNode", _descriptor3, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "roleBagNode", _descriptor4, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "byButtonNode", _descriptor5, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "startGame", _descriptor6, _assertThisInitialized(_this)); // 用于展示结果


          _this.currentShowerRole = {};
          _this.updateShowerRole = {};
          _this.currentShowerSkinNode = void 0;
          _this.currentShowerWeaponNode = void 0; // 当前选择的tab

          _this.currentTab = TAB_INDEX.ROLE_SKIN;
          return _this;
        }

        var _proto = GMainUIRoleAndStoreScript.prototype;

        _proto.getGlobalRoleBag = function getGlobalRoleBag(roleBag) {
          if (!roleBag) {
            return GlobalData.getInstance().get(GameBaseDataConfig.getInstance().ROLE_BAG_KEY);
          }

          return roleBag;
        } // 角色信息展示
        ;

        _proto.initRoleBag = function initRoleBag(onComplete) {
          var _this2 = this;

          var roleBag = this.getGlobalRoleBag(null);
          MyRoleBag.initUpdateRoleInfos();
          this.initRole(roleBag);
          var roleBagScript = this.roleBagNode.getComponent(GTabCardScript);
          roleBagScript.setDataAdapter({
            getTitleItemInfo: function getTitleItemInfo(tabIndex) {
              var info = {
                name: "",
                lock: true,
                valid: true,
                selected: false
              };

              if (tabIndex === TAB_INDEX.ROLE_SKIN.valueOf()) {
                info.name = roleBag.roleSkin.name;
                info.lock = false;
                info.selected = true;
              } else {
                info.valid = false;
              }

              return info;
            },
            getCardItemInfo: function getCardItemInfo(tabIndex, cardItemIndex) {
              var info = {
                name: "",
                lock: true,
                valid: false,
                selected: false
              };

              if (tabIndex === TAB_INDEX.ROLE_SKIN.valueOf()) {
                if (cardItemIndex < roleBag.roleSkin.items.length) {
                  var roleItem = roleBag.roleSkin.items[cardItemIndex];
                  info.name = roleItem.name;
                  info.lock = !roleItem.have;
                  info.valid = true;
                  info.selected = roleItem.id === _this2.updateShowerRole.roleSkin.id;
                }
              }

              return info;
            }
          });
          roleBagScript.setOnClickListener({
            onTitleItemClick: function onTitleItemClick(tabItem) {
              // tab切换
              _this2.currentTab = tabItem.tabIndex;
            },
            onCardItemClick: function onCardItemClick(tabItem, cardItemIndex, node) {
              // 选中内容
              // 进行预览
              if (tabItem.tabIndex === TAB_INDEX.ROLE_SKIN.valueOf()) {
                _this2.updateShowerRole.roleSkin = roleBag.roleSkin.items[cardItemIndex];
              } // 预览


              _this2.updateRoleShower(function () {}); // 购买


              _this2.updateBuyButton(roleBag);
            }
          }); // 开始游戏

          this.startGame.setOnClickOption({
            onClick: function onClick() {
              _this2.backToGame();
            }
          }); // 展示默认

          this.updateBuyButton(roleBag);
          this.updateRoleShower(onComplete);
        };

        _proto.initRole = function initRole(roleBag) {
          this.currentShowerRole.roleSkin = {};
          this.currentShowerRole.weapon = {}; // 根据id查找skin 和weapon

          this.updateShowerRole.roleSkin = roleBag.getRoleSkinById(roleBag.role.roleSkinId);
          this.updateShowerRole.weapon = roleBag.getWeaponById(roleBag.role.weaponId);
        }
        /**
         * 更新展示区域的内容
         */
        ;

        _proto.updateRoleShower = function updateRoleShower(onComplete) {
          var _this3 = this;

          var chainJobs = new JobSystem();
          chainJobs.addAsyncJob(function () {
            return new Promise(function (resolve) {
              if (_this3.updateShowerRole && _this3.updateShowerRole.roleSkin && _this3.updateShowerRole.roleSkin.id !== _this3.currentShowerRole.roleSkin.id) {
                _this3.currentShowerRole.roleSkin.id = _this3.updateShowerRole.roleSkin.id;
                PrefabsUtils.loadRoleSkinById(_this3.currentShowerRole.roleSkin.id, function (data) {
                  if (data) {
                    if (_this3.currentShowerSkinNode) {
                      _this3.currentShowerSkinNode.removeFromParent();
                    } // 取一个样例进行展示


                    _this3.currentShowerSkinNode = instantiate(data[0]);

                    _this3.roleShowerSkinNode.addChild(_this3.currentShowerSkinNode);
                  }

                  resolve();
                });
              } else {
                resolve();
              }
            });
          });
          chainJobs.addAsyncJob(function () {
            return new Promise(function (resolve) {
              if (_this3.updateShowerRole && _this3.updateShowerRole.weapon && _this3.updateShowerRole.weapon.id !== _this3.currentShowerRole.weapon.id) {
                _this3.currentShowerRole.weapon.id = _this3.updateShowerRole.weapon.id;
                PrefabsUtils.loadWeaponById(_this3.currentShowerRole.weapon.id, function (data) {
                  if (data) {
                    if (_this3.currentShowerWeaponNode) {
                      _this3.currentShowerWeaponNode.removeFromParent();
                    }

                    _this3.currentShowerWeaponNode = instantiate(data);

                    _this3.roleShowerWeaponNode.addChild(_this3.currentShowerWeaponNode);
                  }

                  resolve();
                });
              } else {
                resolve();
              }
            });
          });
          chainJobs.addJob(function () {
            onComplete();
          });
          chainJobs.runJobs();
        } // 更新购买按钮
        ;

        _proto.updateBuyButton = function updateBuyButton(roleBag) {
          var _this4 = this;

          roleBag = this.getGlobalRoleBag(roleBag);

          var checkAndUpdateBuyButton = function checkAndUpdateBuyButton(skinOrWeapon) {
            if (skinOrWeapon.have) {
              // 已经拥有，不需要购买
              _this4.byButtonNode.active = false;
            } else {
              // 弹出购买窗口
              _this4.byButtonNode.active = true;

              var priceScript = _this4.byButtonNode.getComponent(GButtonScript); // 钱不够，显示红色


              if (skinOrWeapon.price > roleBag.role.coins) {
                priceScript.setName(JSON.stringify(skinOrWeapon.price) + " 购买");
                priceScript.setNameColor(Color.RED); // 单击无响应

                priceScript.setOnClickOption(null);
              } else {
                priceScript.setName(JSON.stringify(skinOrWeapon.price) + " 购买");
                priceScript.setNameColor(Color.WHITE); // 单击触发购买

                priceScript.setOnClickOption({
                  onClick: function onClick(node) {
                    _this4.processBuy(roleBag, skinOrWeapon);
                  }
                });
              }
            }
          };

          if (this.currentTab == TAB_INDEX.ROLE_SKIN) {
            checkAndUpdateBuyButton(this.updateShowerRole.roleSkin);
          } else {
            this.byButtonNode.active = false;
          }
        }
        /**
         * 走到这里说明购买成功了
         * @param skinOrWeapon 
         */
        ;

        _proto.processBuy = function processBuy(roleBag, skinOrWeapon) {
          roleBag = this.getGlobalRoleBag(roleBag); // 扣除金币

          MyRoleBag.addCoin(-skinOrWeapon.price); // 修改状态

          skinOrWeapon.have = true; // 保存数据

          GlobalData.getInstance().set(GameBaseDataConfig.getInstance().ROLE_BAG_KEY, roleBag);
          ResourcesUtils.saveToPlatform(GameBaseDataConfig.getInstance().ROLE_BAG_PATH, roleBag); // 更新展示列表

          var roleBagScript = this.roleBagNode.getComponent(GTabCardScript);
          roleBagScript.updteData();
        }
        /**
         * 返回游戏，检查选中的装备是否已经拥有
         * 如果已经拥有则更新role
         */
        ;

        _proto.backToGame = function backToGame() {
          var roleBag = this.getGlobalRoleBag(null);
          var needReSave = false;

          if (this.updateShowerRole.roleSkin.have) {
            if (roleBag.role.roleSkinId !== this.updateShowerRole.roleSkin.id) {
              roleBag.role.roleSkinId = this.updateShowerRole.roleSkin.id;
              needReSave = true;
            }
          }

          if (this.updateShowerRole.weapon && this.updateShowerRole.weapon.have) {
            if (roleBag.role.weaponId !== this.updateShowerRole.weapon.id) {
              roleBag.role.weaponId = this.updateShowerRole.weapon.id;
              needReSave = true;
            }
          }

          if (needReSave) {
            // 保存数据
            GlobalData.getInstance().set(GameBaseDataConfig.getInstance().ROLE_BAG_KEY, roleBag);
            ResourcesUtils.saveToPlatform(GameBaseDataConfig.getInstance().ROLE_BAG_PATH, roleBag);
          } // 开始游戏


          var totalLevels = GlobalData.getInstance().get(GameBaseDataConfig.getInstance().LEVEL_DATA_KEY);
          var currentLevel = MyLevelUtils.getFirstNotCompleteLevel(totalLevels);
          GlobalData.getInstance().set(GameBaseDataConfig.getInstance().LEVEL_CURRENT_KEY, currentLevel);
          director.loadScene('level');
        };

        return GMainUIRoleAndStoreScript;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "roleShowerNode", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "roleShowerSkinNode", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "roleShowerWeaponNode", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor4 = _applyDecoratedDescriptor(_class2.prototype, "roleBagNode", [_dec5], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor5 = _applyDecoratedDescriptor(_class2.prototype, "byButtonNode", [_dec6], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor6 = _applyDecoratedDescriptor(_class2.prototype, "startGame", [_dec7], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GOpenOtherGame.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './GDialogGridViewScript.ts', './GButtonScript.ts', './Share.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Node, Prefab, instantiate, Component, GDialogGridViewScript, GButtonScript, Share;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Node = module.Node;
      Prefab = module.Prefab;
      instantiate = module.instantiate;
      Component = module.Component;
    }, function (module) {
      GDialogGridViewScript = module.GDialogGridViewScript;
    }, function (module) {
      GButtonScript = module.GButtonScript;
    }, function (module) {
      Share = module.Share;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _class, _class2, _descriptor, _descriptor2, _descriptor3;

      cclegacy._RF.push({}, "cbb31Tj1a1CpJ5ZYq5luIA0", "GOpenOtherGame", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      /**
       * 游戏矩阵
       * 包含 更多游戏按钮 和一个游戏grid
       */

      var GOpenOtherGame = exports('GOpenOtherGame', (_dec = ccclass('GOpenOtherGame'), _dec2 = property(Node), _dec3 = property(Node), _dec4 = property(Prefab), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GOpenOtherGame, _Component);

        function GOpenOtherGame() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "moreGameNode", _descriptor, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "gameGridViewNode", _descriptor2, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "gameGridViewItemPrefab", _descriptor3, _assertThisInitialized(_this));

          _this.games = [{
            name: "消消Master",
            appid: "wx4bda6d0d9879efab"
          }, {
            name: "3D箭头消除",
            appid: "wx940b06615c290833"
          }];
          return _this;
        }

        var _proto = GOpenOtherGame.prototype;

        _proto.onLoad = function onLoad() {
          var _this2 = this; // 点击按钮就显示内容，否则不显示


          this.moreGameNode.getComponent(GButtonScript).setOnClickOption({
            onClick: function onClick() {
              _this2.gameGridViewNode.active = true;

              _this2.gameGridViewNode.getComponent(GDialogGridViewScript).show(function () {
                // GDialogGridViewScript设置了不自动删除，可以重复利用，隐藏的时候仅修改active
                _this2.gameGridViewNode.active = false;
              });
            }
          }); // 设置显示的内容

          this.gameGridViewNode.getComponent(GDialogGridViewScript).setDataAdapter({
            getCount: function getCount() {
              return _this2.games.length;
            },
            getNode: function getNode(position, parentNode) {
              var gameItem = _this2.games[position];
              var node = instantiate(_this2.gameGridViewItemPrefab);
              var nodeScript = node.getComponent(GButtonScript);
              nodeScript.setName(gameItem.name);
              nodeScript.setOnClickOption({
                onClick: function onClick(n) {
                  new Share().openOtherGame(gameItem.appid);
                }
              });
              return node;
            }
          });
        };

        _proto.update = function update(deltaTime) {};

        return GOpenOtherGame;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "moreGameNode", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "gameGridViewNode", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "gameGridViewItemPrefab", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GSettingsScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './AudioManager.ts', './GlobalData.ts', './VibrateManager.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Sprite, SpriteFrame, Label, Component, AudioManager, GlobalData, VibrateManager;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Sprite = module.Sprite;
      SpriteFrame = module.SpriteFrame;
      Label = module.Label;
      Component = module.Component;
    }, function (module) {
      AudioManager = module.AudioManager;
    }, function (module) {
      GlobalData = module.GlobalData;
    }, function (module) {
      VibrateManager = module.VibrateManager;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _class, _class2, _descriptor, _descriptor2, _descriptor3, _descriptor4, _descriptor5;

      cclegacy._RF.push({}, "1104d0jxApCp5FjdPnKFtje", "GSettingsScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var GSettingsScript = exports('GSettingsScript', (_dec = ccclass("GSettingsScript"), _dec2 = property(Sprite), _dec3 = property(Sprite), _dec4 = property(SpriteFrame), _dec5 = property(SpriteFrame), _dec6 = property(Label), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GSettingsScript, _Component);

        function GSettingsScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;
          /* class member could be defined like this */
          // dummy = '';

          _initializerDefineProperty(_this, "spVibrateSwitch", _descriptor, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "spSoundSwitch", _descriptor2, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "imgSwitchOpen", _descriptor3, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "imgSwitchClose", _descriptor4, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "lbVersion", _descriptor5, _assertThisInitialized(_this));

          _this.isSoundOpen = void 0;
          _this.isVibrateOpen = void 0;
          return _this;
        }

        GSettingsScript.checkState = function checkState() {
          var data = AudioManager.instance.getConfiguration(true);

          if (!data) {
            AudioManager.instance.closeMusic();
            AudioManager.instance.closeSound();
          } else {
            AudioManager.instance.openMusic();
            AudioManager.instance.openSound();
          }
        };

        var _proto = GSettingsScript.prototype;

        _proto.start = function start() {
          // Your initialization goes here.
          this.show();
        };

        _proto.show = function show() {
          this.isSoundOpen = AudioManager.instance.getConfiguration(true);
          this.isVibrateOpen = GlobalData.instance.getGlobalStorgeData(VibrateManager.GLOBAL_KEY_VIBRATE_ENABLE) ? true : false;
          this.refreshSwitchUI();
        };

        _proto.refreshSwitchUI = function refreshSwitchUI() {
          if (this.isVibrateOpen) {
            this.spVibrateSwitch.spriteFrame = this.imgSwitchOpen;
          } else {
            this.spVibrateSwitch.spriteFrame = this.imgSwitchClose;
          }

          if (this.isSoundOpen) {
            this.spSoundSwitch.spriteFrame = this.imgSwitchOpen;
          } else {
            this.spSoundSwitch.spriteFrame = this.imgSwitchClose;
          }
        };

        _proto.onBtnVibrateClick = function onBtnVibrateClick() {
          this.isVibrateOpen = !this.isVibrateOpen;
          GlobalData.instance.setGlobalStorgeData(VibrateManager.GLOBAL_KEY_VIBRATE_ENABLE, this.isVibrateOpen);
          this.refreshSwitchUI();
        };

        _proto.onBtnSoundClick = function onBtnSoundClick() {
          this.isSoundOpen = !this.isSoundOpen;

          if (!this.isSoundOpen) {
            AudioManager.instance.closeMusic();
            AudioManager.instance.closeSound();
          } else {
            AudioManager.instance.openMusic();
            AudioManager.instance.openSound();
          }

          GlobalData.instance.setGlobalStorgeData('music', "" + this.isSoundOpen);
          this.refreshSwitchUI();
        };

        _proto.onBtnCloseClick = function onBtnCloseClick() {// todo
        } // update (deltaTime: number) {
        //     // Your update function goes here.
        // }
        ;

        return GSettingsScript;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "spVibrateSwitch", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return null;
        }
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "spSoundSwitch", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return null;
        }
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "imgSwitchOpen", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return null;
        }
      }), _descriptor4 = _applyDecoratedDescriptor(_class2.prototype, "imgSwitchClose", [_dec5], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return null;
        }
      }), _descriptor5 = _applyDecoratedDescriptor(_class2.prototype, "lbVersion", [_dec6], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return null;
        }
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GTabCardItemScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './GButtonScript.ts', './GGridViewScript.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Component, GButtonScript, GGridViewScript;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Component = module.Component;
    }, function (module) {
      GButtonScript = module.GButtonScript;
    }, function (module) {
      GGridViewScript = module.GGridViewScript;
    }],
    execute: function () {
      var _dec, _dec2, _class, _class2, _descriptor;

      cclegacy._RF.push({}, "324cepjcWxHb5q65fCFUkrc", "GTabCardItemScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var GTabCardItemScript = exports('GTabCardItemScript', (_dec = ccclass('GTabCardItemScript'), _dec2 = property(GGridViewScript), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GTabCardItemScript, _Component);

        function GTabCardItemScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "gridView", _descriptor, _assertThisInitialized(_this));

          _this.items = [];
          _this.itemScripts = []; // 记录上一次选择的item，便于重置选中 状态

          _this.lastSelectedItem = void 0;
          _this.clickOption = void 0;
          return _this;
        }

        var _proto = GTabCardItemScript.prototype;

        _proto.onLoad = function onLoad() {
          var _this2 = this;

          this.items = this.gridView.contentNode.children;

          var _loop = function _loop(_index) {
            var item = _this2.items[_index];

            _this2.itemScripts.push(item.getComponent(GButtonScript));

            item.getComponent(GButtonScript).setOnClickOption({
              onClick: function onClick(node) {
                // 设置选中状态
                _this2.setSelectedItemIndex(_index);

                _this2.clickOption.onClick(item, _index);
              }
            });
          };

          for (var _index = 0; _index < this.items.length; _index++) {
            _loop(_index);
          }
        };

        _proto.update = function update(deltaTime) {};

        _proto.setVisible = function setVisible(flag) {
          this.node.active = flag;
        };

        _proto.setSelectedItemIndex = function setSelectedItemIndex(itemIndex) {
          var item = this.items[itemIndex];

          if (this.lastSelectedItem) {
            this.lastSelectedItem.getComponent(GButtonScript).setSelectd(false);
          }

          this.lastSelectedItem = item;
          this.lastSelectedItem.getComponent(GButtonScript).setSelectd(true);
        };

        _proto.setOnClickListener = function setOnClickListener(clickOption) {
          this.clickOption = clickOption;
        };

        return GTabCardItemScript;
      }(Component), _descriptor = _applyDecoratedDescriptor(_class2.prototype, "gridView", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GTabCardScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './GTabCardTitleScript.ts', './GTabCardItemScript.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, _createForOfIteratorHelperLoose, cclegacy, _decorator, Node, Component, GTabCardTitleScript, GTabCardItemScript;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
      _createForOfIteratorHelperLoose = module.createForOfIteratorHelperLoose;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Node = module.Node;
      Component = module.Component;
    }, function (module) {
      GTabCardTitleScript = module.GTabCardTitleScript;
    }, function (module) {
      GTabCardItemScript = module.GTabCardItemScript;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _class, _class2, _descriptor, _descriptor2;

      cclegacy._RF.push({}, "d83bcjk9TBHtKFRs1SiyuhE", "GTabCardScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var TabItem = exports('TabItem', /*#__PURE__*/function () {
        function TabItem() {
          this.title = void 0;
          this.titleScript = void 0;
          this.card = void 0;
          this.cardScript = void 0; // 当前是否被选中

          this.selected = false; // 在tab中的顺序

          this.tabIndex = 0; // 如果被锁定了操作无效

          this.lock = false;
        }

        var _proto = TabItem.prototype; // 修改标题名称

        _proto.setTitleName = function setTitleName(name) {
          if (this.titleScript) {
            this.titleScript.button.setName(name);
          }
        };

        return TabItem;
      }());
      /**
       * 支持tab切换
       * 支持每个tab单击响应
       * 注意：目前支持3个tab，且card中支持15个元素是固定的
       */

      var GTabCardScript = exports('GTabCardScript', (_dec = ccclass('GTabCardScript'), _dec2 = property(Node), _dec3 = property(Node), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GTabCardScript, _Component);

        function GTabCardScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "titleCardNode", _descriptor, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "conCardNode", _descriptor2, _assertThisInitialized(_this)); // TabItem列表


          _this.tabItems = []; // 当前显示的tabIndex

          _this.curTabIndex = 0;
          _this.curTabConIndex = 0; // 数据适配

          _this.dataAdapter = void 0; // 单击事件

          _this.clickListener = void 0;
          return _this;
        }

        var _proto2 = GTabCardScript.prototype;

        _proto2.onLoad = function onLoad() {
          var _this2 = this;

          var len = this.titleCardNode.children.length;

          var _loop = function _loop(index) {
            var item = new TabItem();
            item.title = _this2.titleCardNode.children[index];
            item.card = _this2.conCardNode.children[index];
            item.selected = index === _this2.curTabIndex;
            item.tabIndex = index; // 注册监听

            item.titleScript = item.title.getComponent(GTabCardTitleScript);
            item.titleScript.setOnClickListener({
              onClick: function onClick(node) {
                _this2.onTabTitleClick(index);
              }
            }); // 注册监听

            item.cardScript = item.card.getComponent(GTabCardItemScript);
            item.cardScript.setOnClickListener({
              onClick: function onClick(tabConNode, tabConIndex) {
                _this2.onTabConClick(tabConNode, tabConIndex);
              }
            });

            _this2.tabItems.push(item);
          };

          for (var index = 0; index < len; index++) {
            _loop(index);
          }
        };

        _proto2.start = function start() {
          this.updateTabVisible();
        };

        _proto2.updateTabVisible = function updateTabVisible() {
          for (var _iterator = _createForOfIteratorHelperLoose(this.tabItems), _step; !(_step = _iterator()).done;) {
            var item = _step.value;
            item.titleScript.setSelected(item.selected); // 没有被选中的卡片，不用显示

            item.cardScript.setVisible(item.selected);
          }
        };

        _proto2.onTabTitleClick = function onTabTitleClick(index) {
          // 调整选中
          this.tabItems[this.curTabIndex].selected = false;
          var item = this.tabItems[index];
          item.selected = true;
          this.curTabIndex = index;
          this.updateTabVisible();

          if (this.clickListener) {
            this.clickListener.onTitleItemClick(item);
          }
        };

        _proto2.onTabConClick = function onTabConClick(tabConNode, index) {
          // 调整选中
          var item = this.tabItems[this.curTabIndex];
          this.curTabConIndex = index;

          if (this.clickListener) {
            this.clickListener.onCardItemClick(item, index, tabConNode);
          }
        };

        _proto2.setDataAdapter = function setDataAdapter(adapter) {
          this.dataAdapter = adapter;
          this.updteData();
        };

        _proto2.updteData = function updteData() {
          if (!this.dataAdapter) {
            return;
          }

          for (var _iterator2 = _createForOfIteratorHelperLoose(this.tabItems), _step2; !(_step2 = _iterator2()).done;) {
            var _tabItem = _step2.value;
            var titleItemInfo = this.dataAdapter.getTitleItemInfo(_tabItem.tabIndex);

            _tabItem.titleScript.button.setName(titleItemInfo.name);

            _tabItem.titleScript.button.setLocked(titleItemInfo.lock);

            _tabItem.selected = titleItemInfo.selected;

            if (titleItemInfo.selected) {
              this.curTabIndex = _tabItem.tabIndex;
            } // 不支持的设置不显示


            _tabItem.title.active = titleItemInfo.valid;
            var cardItemLen = _tabItem.cardScript.itemScripts.length;

            for (var index = 0; index < cardItemLen; index++) {
              var cardItem = _tabItem.cardScript.itemScripts[index];
              var info = this.dataAdapter.getCardItemInfo(_tabItem.tabIndex, index);
              cardItem.setName(info.name);
              cardItem.setLocked(info.lock); // 不支持的设置不显示

              _tabItem.cardScript.items[index].active = info.valid;

              if (info.selected) {
                this.curTabConIndex = index;

                _tabItem.cardScript.setSelectedItemIndex(index);
              }
            }
          }

          this.updateTabVisible();
        };

        _proto2.setOnClickListener = function setOnClickListener(clickListener) {
          this.clickListener = clickListener;
        };

        return GTabCardScript;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "titleCardNode", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "conCardNode", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GTabCardTitleScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './GButtonScript.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Node, Component, GButtonScript;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Node = module.Node;
      Component = module.Component;
    }, function (module) {
      GButtonScript = module.GButtonScript;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _class, _class2, _descriptor, _descriptor2;

      cclegacy._RF.push({}, "4e443tueRJAFpUHxCzKQl7K", "GTabCardTitleScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var GTabCardTitleScript = exports('GTabCardTitleScript', (_dec = ccclass('GTabCardTitleScript'), _dec2 = property(Node), _dec3 = property(GButtonScript), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GTabCardTitleScript, _Component);

        function GTabCardTitleScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "bgNode", _descriptor, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "button", _descriptor2, _assertThisInitialized(_this));

          _this.clickOption = void 0;
          return _this;
        }

        var _proto = GTabCardTitleScript.prototype;

        _proto.start = function start() {
          this.button.setOnClickOption(this.clickOption);
        };

        _proto.update = function update(deltaTime) {};

        _proto.setSelected = function setSelected(flag) {
          this.bgNode.active = flag;
        };

        _proto.setOnClickListener = function setOnClickListener(clickOption) {
          this.clickOption = clickOption;
        };

        return GTabCardTitleScript;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "bgNode", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "button", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/GToastScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc'], function (exports) {
  var _inheritsLoose, cclegacy, _decorator, UITransform, Vec3, Label, tween, instantiate, Component;

  return {
    setters: [function (module) {
      _inheritsLoose = module.inheritsLoose;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      UITransform = module.UITransform;
      Vec3 = module.Vec3;
      Label = module.Label;
      tween = module.tween;
      instantiate = module.instantiate;
      Component = module.Component;
    }],
    execute: function () {
      var _dec, _class;

      cclegacy._RF.push({}, "5f31d+MpklFcJekmgiEmqTC", "GToastScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      /**
       * Toast 提示，支持显示时间
       */

      var GToastScript = exports('GToastScript', (_dec = ccclass('GToastScript'), _dec(_class = /*#__PURE__*/function (_Component) {
        _inheritsLoose(GToastScript, _Component);

        function GToastScript() {
          return _Component.apply(this, arguments) || this;
        }

        var _proto = GToastScript.prototype;

        _proto.onLoad = function onLoad() {}
        /**
         * 弹出一个Toast, 位置在屏幕下方
         * 一段时间后自动移除
         * @param message 
         * @param duration 
         */
        ;

        _proto.show = function show(canvsNode, message, duration) {
          var _this = this;

          if (duration === void 0) {
            duration = 2;
          } // 设置Toast节点的位置 TODO 3d中node可能没有UITransform


          var canvasSize = canvsNode.getComponent(UITransform).contentSize;
          var toastPosition = new Vec3(0, -canvasSize.height / 4, 0); // 设置位置为屏幕下方

          canvsNode.addChild(this.node);
          this.node.getComponent(Label).string = message;
          this.node.setPosition(toastPosition); // 设置Toast显示动画效果

          tween(this.node).delay(duration).to(0.01, {
            scale: new Vec3(0, 0, 0)
          }).call(function () {
            _this.node.removeFromParent();
          }).start();
        };

        GToastScript.showToast = function showToast(toastPrefab, canvsNode, message, duration) {
          if (duration === void 0) {
            duration = 0.5;
          }

          var node = instantiate(toastPrefab);
          node.getComponent(GToastScript).show(canvsNode, message, duration);
        };

        return GToastScript;
      }(Component)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/HomeScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './GlobalData.ts', './GButtonScript.ts', './MyLevel.ts', './Level.ts', './GLabelScoreScript.ts', './Strings.ts', './GButtonShareScript.ts', './GDialogGridViewScript.ts', './LoginBase.ts', './CloudAndStorageData.ts', './MyRoleBag.ts', './GMainUIRoleAndStoreScript.ts', './JobSystem.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Node, Prefab, director, instantiate, Color, GlobalData, GButtonScript, MyLevel, MyLevelUtils, LevelUtil, GLabelScoreScript, Strings, GButtonShareScript, GDialogGridViewScript, GameBaseDataConfig, LoginBase, CloudAndStorageDataMergeUtils, MyRoleBag, GMainUIRoleAndStoreScript, JobSystem;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Node = module.Node;
      Prefab = module.Prefab;
      director = module.director;
      instantiate = module.instantiate;
      Color = module.Color;
    }, function (module) {
      GlobalData = module.GlobalData;
    }, function (module) {
      GButtonScript = module.GButtonScript;
    }, function (module) {
      MyLevel = module.MyLevel;
      MyLevelUtils = module.MyLevelUtils;
    }, function (module) {
      LevelUtil = module.LevelUtil;
    }, function (module) {
      GLabelScoreScript = module.GLabelScoreScript;
    }, function (module) {
      Strings = module.Strings;
    }, function (module) {
      GButtonShareScript = module.GButtonShareScript;
    }, function (module) {
      GDialogGridViewScript = module.GDialogGridViewScript;
    }, function (module) {
      GameBaseDataConfig = module.GameBaseDataConfig;
      LoginBase = module.LoginBase;
    }, function (module) {
      CloudAndStorageDataMergeUtils = module.CloudAndStorageDataMergeUtils;
    }, function (module) {
      MyRoleBag = module.MyRoleBag;
    }, function (module) {
      GMainUIRoleAndStoreScript = module.GMainUIRoleAndStoreScript;
    }, function (module) {
      JobSystem = module.JobSystem;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _class, _class2, _descriptor, _descriptor2, _descriptor3, _descriptor4, _descriptor5, _descriptor6, _descriptor7, _class3;

      cclegacy._RF.push({}, "215c4oMnJZMlpz1ccwrME/f", "HomeScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      /**
       * 读取角色信息
       * 读取关卡信息
       * 
       */

      var HomeScript = exports('HomeScript', (_dec = ccclass('HomeScript'), _dec2 = property(Node), _dec3 = property(Node), _dec4 = property(Node), _dec5 = property(Node), _dec6 = property(Prefab), _dec7 = property(Prefab), _dec8 = property(GMainUIRoleAndStoreScript), _dec(_class = (_class2 = (_class3 = /*#__PURE__*/function (_LoginBase) {
        _inheritsLoose(HomeScript, _LoginBase);

        function HomeScript() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _LoginBase.call.apply(_LoginBase, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "startNode", _descriptor, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "shareNode", _descriptor2, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "currentLevelValueNode", _descriptor3, _assertThisInitialized(_this)); // 总关卡信息


          _initializerDefineProperty(_this, "levelsNode", _descriptor4, _assertThisInitialized(_this)); // 


          _initializerDefineProperty(_this, "levelItemPrefab", _descriptor5, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "levelsDialogPrefab", _descriptor6, _assertThisInitialized(_this)); // rolebag


          _initializerDefineProperty(_this, "roleAndStore", _descriptor7, _assertThisInitialized(_this));

          return _this;
        }

        var _proto = HomeScript.prototype;

        _proto.onLoad = function onLoad() {
          var _this2 = this;

          var jobSystem = new JobSystem();
          jobSystem.addAsyncJob(function () {
            return new Promise(function (resolve) {
              // 读取角色信息
              _this2.loadRoleBag(new CloudAndStorageDataMergeUtils(MyRoleBag), function () {
                resolve();
              });
            });
          });
          jobSystem.addAsyncJob(function () {
            return new Promise(function (resolve) {
              _this2.login(new LevelUtil(MyLevel), function (levels) {
                _this2.onLevelResourceLoaded(levels);

                resolve();
              });
            });
          });
          jobSystem.addAsyncJob(function () {
            return new Promise(function (resolve) {
              _this2.roleAndStore.initRoleBag(function () {
                resolve();
              });
            });
          });
          jobSystem.addJob(function () {
            // 分享
            _this2.shareNode.getComponent(GButtonShareScript).setOnClickOption({
              getShareMessage: function getShareMessage() {
                return Strings.SHARE_MESSAGE;
              }
            }); // 关卡


            _this2.levelsNode.getComponent(GButtonScript).setOnClickOption({
              onClick: function onClick() {
                // 弹出菜单
                _this2.showLevels();
              }
            });
          });
          jobSystem.addJob(function () {
            // 首次打开，直接开始游戏
            if (!GlobalData.instance.get(HomeScript.FIRST_ENTER_HOME_KEY)) {
              director.loadScene('level');
            }

            GlobalData.instance.set(HomeScript.FIRST_ENTER_HOME_KEY, true);
          });
          jobSystem.runJobs();
        } // 关卡加载完毕
        ;

        _proto.onLevelResourceLoaded = function onLevelResourceLoaded(levels) {
          var _this3 = this;

          var totalLevels = GlobalData.getInstance().get(GameBaseDataConfig.getInstance().LEVEL_DATA_KEY);
          var currentLevel = MyLevelUtils.getFirstNotCompleteLevel(totalLevels);
          GlobalData.getInstance().set(GameBaseDataConfig.getInstance().LEVEL_CURRENT_KEY, currentLevel);
          this.updateCurrentLevelNode();
          this.startNode.getComponent(GButtonScript).setOnClickOption({
            onClick: function onClick(node) {
              var currentLevel = MyLevelUtils.getFirstNotCompleteLevel(totalLevels);
              GlobalData.getInstance().set(GameBaseDataConfig.getInstance().LEVEL_CURRENT_KEY, currentLevel);

              _this3.updateCurrentLevelNode();

              director.loadScene('level');
            }
          });
        }
        /**
         * 更新关卡情况
         */
        ;

        _proto.updateCurrentLevelNode = function updateCurrentLevelNode() {
          var currentLevel = GlobalData.getInstance().get(GameBaseDataConfig.getInstance().LEVEL_CURRENT_KEY);
          this.currentLevelValueNode.getComponent(GLabelScoreScript).setScore(currentLevel.levelIndex);
        }
        /**
         * 显示所有关卡
         */
        ;

        _proto.showLevels = function showLevels() {
          var _this4 = this;

          var levels = GlobalData.getInstance().get(GameBaseDataConfig.getInstance().LEVEL_DATA_KEY);
          var dialog = instantiate(this.levelsDialogPrefab);
          var dialogScript = dialog.getComponent(GDialogGridViewScript);
          this.node.addChild(dialog);
          dialogScript.setDataAdapter({
            getCount: function getCount() {
              return levels.length;
            },
            getNode: function getNode(position, parentNode) {
              var level = levels[position];
              var node = instantiate(_this4.levelItemPrefab);
              var nodeScript = node.getComponent(GButtonScript);
              nodeScript.setName(level.levelScene + " " + JSON.stringify(level.levelIndex));

              if (levels[position].complete) {
                // 已完成的显示不一样
                nodeScript.setBackgroundColor(new Color(204, 141, 61, 255));
              }

              nodeScript.setOnClickOption({
                onClick: function onClick(n) {
                  var currentLevel = levels[position];
                  GlobalData.getInstance().set(GameBaseDataConfig.getInstance().LEVEL_CURRENT_KEY, currentLevel);

                  _this4.updateCurrentLevelNode();

                  director.loadScene('level');
                }
              });
              return node;
            }
          });
          dialogScript.setTitleValue("关卡");
          dialogScript.show();
        };

        return HomeScript;
      }(LoginBase), _class3.FIRST_ENTER_HOME_KEY = "FIRST_ENTER_HOME_KEY", _class3), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "startNode", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "shareNode", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "currentLevelValueNode", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor4 = _applyDecoratedDescriptor(_class2.prototype, "levelsNode", [_dec5], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor5 = _applyDecoratedDescriptor(_class2.prototype, "levelItemPrefab", [_dec6], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor6 = _applyDecoratedDescriptor(_class2.prototype, "levelsDialogPrefab", [_dec7], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor7 = _applyDecoratedDescriptor(_class2.prototype, "roleAndStore", [_dec8], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/JobSystem.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc'], function (exports) {
  var _asyncToGenerator, _regeneratorRuntime, cclegacy;

  return {
    setters: [function (module) {
      _asyncToGenerator = module.asyncToGenerator;
      _regeneratorRuntime = module.regeneratorRuntime;
    }, function (module) {
      cclegacy = module.cclegacy;
    }],
    execute: function () {
      cclegacy._RF.push({}, "c2742WsvZFAx45YGKJSqY8m", "JobSystem", undefined);

      var JobSystem = exports('JobSystem', /*#__PURE__*/function () {
        function JobSystem() {
          this.nextJobId = void 0;
          this.jobs = void 0;
          this.nextJobId = 1;
          this.jobs = [];
        }

        var _proto = JobSystem.prototype;

        _proto.addJob = function addJob(task, priority) {
          if (priority === void 0) {
            priority = 0;
          }

          var job = {
            id: this.nextJobId,
            priority: priority,
            task: task
          };
          this.nextJobId++; // 自增生成下一个任务的 ID

          this.jobs.push(job);
          this.sortJobsByPriority();
          return job;
        };

        _proto.addAsyncJob = function addAsyncJob(asyncTask, priority) {
          if (priority === void 0) {
            priority = 0;
          }

          var job = {
            id: this.nextJobId,
            priority: priority,
            asyncTask: asyncTask
          };
          this.nextJobId++; // 自增生成下一个任务的 ID

          this.jobs.push(job);
          this.sortJobsByPriority();
          return job;
        };

        _proto.sortJobsByPriority = function sortJobsByPriority() {
          this.jobs.sort(function (a, b) {
            return b.priority - a.priority;
          });
        };

        _proto.runJobs = /*#__PURE__*/function () {
          var _runJobs = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
            var job;
            return _regeneratorRuntime().wrap(function _callee$(_context) {
              while (1) switch (_context.prev = _context.next) {
                case 0:
                  if (!(this.jobs.length > 0)) {
                    _context.next = 12;
                    break;
                  }

                  job = this.jobs.shift();

                  if (!job) {
                    _context.next = 10;
                    break;
                  }

                  if (!job.task) {
                    _context.next = 7;
                    break;
                  }

                  job.task();
                  _context.next = 10;
                  break;

                case 7:
                  if (!job.asyncTask) {
                    _context.next = 10;
                    break;
                  }

                  _context.next = 10;
                  return job.asyncTask();

                case 10:
                  _context.next = 0;
                  break;

                case 12:
                case "end":
                  return _context.stop();
              }
            }, _callee, this);
          }));

          function runJobs() {
            return _runJobs.apply(this, arguments);
          }

          return runJobs;
        }();

        _proto.empty = function empty() {
          return this.jobs.length === 0;
        };

        return JobSystem;
      }());

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/Level.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc'], function (exports) {
  var _createForOfIteratorHelperLoose, cclegacy, _decorator;

  return {
    setters: [function (module) {
      _createForOfIteratorHelperLoose = module.createForOfIteratorHelperLoose;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
    }],
    execute: function () {
      cclegacy._RF.push({}, "6dacbx6S7ROhraFvamUtJBf", "Level", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var ILevel = exports('ILevel', function ILevel() {
        this.levelIndex = 0;
        this.levelScene = '';
        this.complete = false;
      });
      var LevelUtil = exports('LevelUtil', /*#__PURE__*/function () {
        function LevelUtil(levelType) {
          this.levelType = void 0;
          this.levelType = levelType;
        }

        var _proto = LevelUtil.prototype;

        _proto.loadFromJson = function loadFromJson(json) {
          var levelDataArray = json.json;
          var levels = [];

          for (var _iterator = _createForOfIteratorHelperLoose(levelDataArray), _step; !(_step = _iterator()).done;) {
            var levelData = _step.value;
            var level = new this.levelType();
            level.fromJsonObj(levelData);
            levels.push(level);
          }

          return levels;
        };

        _proto.loadFromJsonString = function loadFromJsonString(str) {
          var levelDataArray = JSON.parse(str);
          var levels = [];

          for (var _iterator2 = _createForOfIteratorHelperLoose(levelDataArray), _step2; !(_step2 = _iterator2()).done;) {
            var levelData = _step2.value;
            var level = new this.levelType();
            level.fromJsonObj(levelData);
            levels.push(level);
          }

          return levels;
        }
        /**
         * 远端结果和本地缓存合并，结果会更新到levels中
         * @param levels 远端更新
         * @param localStorageLevels 本地缓存
         * @returns 
         */
        ;

        _proto.mergeLevels = function mergeLevels(levels, localStorageLevels) {
          // 根据getLevelUid进行合并
          levels.forEach(function (element) {
            for (var index = 0; index < localStorageLevels.length; index++) {
              var localLevel = localStorageLevels[index];

              if (element.getLevelUid() === localLevel.getLevelUid()) {
                localLevel.copyLevelResult(element);
                break;
              }
            }
          });
          return levels;
        };

        LevelUtil.getFirstNotCompleteLevel = function getFirstNotCompleteLevel(levels, levelScene) {
          if (levelScene === void 0) {
            levelScene = '';
          }

          var sceneLevel = [];

          for (var index = 0; index < levels.length; index++) {
            var element = levels[index];

            if (element.levelScene === levelScene) {
              sceneLevel.push(element);
            }
          }

          for (var _index = 0; _index < sceneLevel.length; _index++) {
            var _element = sceneLevel[_index];

            if (_element.levelScene === levelScene) {
              if (!_element.complete) {
                return _element;
              }
            }
          } // 全部完成，返回最后


          return sceneLevel[sceneLevel.length - 1];
        };

        return LevelUtil;
      }());

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/LoginBase.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './ResourcesUtils.ts', './GlobalData.ts'], function (exports) {
  var _inheritsLoose, cclegacy, _decorator, Component, ResourcesUtils, GlobalData;

  return {
    setters: [function (module) {
      _inheritsLoose = module.inheritsLoose;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Component = module.Component;
    }, function (module) {
      ResourcesUtils = module.ResourcesUtils;
    }, function (module) {
      GlobalData = module.GlobalData;
    }],
    execute: function () {
      var _dec, _class;

      cclegacy._RF.push({}, "75e49d8A1NDWJ1I6bTwX+1L", "LoginBase", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property; // 一些配置 主要是资源路径，建议在初始化的时候修改，避免重复

      var GameBaseDataConfig = exports('GameBaseDataConfig', /*#__PURE__*/function () {
        function GameBaseDataConfig() {
          this.LEVEL_DATA_PATH = "level_details/levels";
          this.LEVEL_DATA_KEY = "levels_data";
          this.LEVEL_CURRENT_KEY = "level_data_current";
          this.ROLE_BAG_PATH = "level_details/rolebag";
          this.ROLE_BAG_KEY = "rolebag";
        }

        GameBaseDataConfig.getInstance = function getInstance() {
          if (!this.instance) {
            this.instance = new GameBaseDataConfig();
          }

          return this.instance;
        };

        var _proto = GameBaseDataConfig.prototype;

        _proto.initByGameName = function initByGameName(GAME_NAME) {
          this.LEVEL_DATA_PATH = "data/" + GAME_NAME + "_levels";
          this.LEVEL_DATA_KEY = GAME_NAME + "_levels_data";
          this.LEVEL_CURRENT_KEY = GAME_NAME + "_level_data_current";
          this.ROLE_BAG_PATH = "data/" + GAME_NAME + "_rolebag";
          this.ROLE_BAG_KEY = GAME_NAME + "_rolebag";
        };

        return GameBaseDataConfig;
      }());
      /**
       * 1、读取resource的资源（关卡信息）
       * 2、读取本地资源（本地记录）
       * 3、合并资源
       * 需要调用login方法
       */

      GameBaseDataConfig.instance = undefined;
      var LoginBase = exports('LoginBase', (_dec = ccclass('LoginBase'), _dec(_class = /*#__PURE__*/function (_Component) {
        _inheritsLoose(LoginBase, _Component);

        function LoginBase() {
          return _Component.apply(this, arguments) || this;
        }

        var _proto2 = LoginBase.prototype;

        _proto2.login = function login(levelUtils, onLevelResourceLoadedCallback) {
          var _this = this; // 显示进度条， 处理信息之后，跳转场景


          ResourcesUtils.startLoadJson(GameBaseDataConfig.getInstance().LEVEL_DATA_PATH, function (data) {
            // 读取关卡资源，可能会游戏发布更新
            var levels = levelUtils.loadFromJson(data); // 读取本地进度

            var localStorageData = ResourcesUtils.getFromPlatform(GameBaseDataConfig.getInstance().LEVEL_DATA_PATH);

            if (localStorageData) {
              // 合并数据，使用本地进去更新关卡资源
              var localStorageLevels = levelUtils.loadFromJsonString(localStorageData);
              levels = levelUtils.mergeLevels(levels, localStorageLevels);
            } // 存到全局变量中


            GlobalData.getInstance().set(GameBaseDataConfig.getInstance().LEVEL_DATA_KEY, levels);

            if (onLevelResourceLoadedCallback) {
              onLevelResourceLoadedCallback(levels);
            } else {
              _this.onLevelResourceLoaded(levels);
            }
          });
        };

        _proto2.loadRoleBag = function loadRoleBag(rolebagUtils, onComplete) {
          // 读取角色背包信息
          ResourcesUtils.startLoadJson(GameBaseDataConfig.getInstance().ROLE_BAG_PATH, function (data) {
            var rolebag = rolebagUtils.loadFromJson(data); // 读取本地进度

            var localStorageData = ResourcesUtils.getFromPlatform(GameBaseDataConfig.getInstance().ROLE_BAG_PATH);

            if (localStorageData) {
              // 合并数据，使用本地进去更新关卡资源
              var localStorageLevels = rolebagUtils.loadFromJsonString(localStorageData);
              rolebag = rolebagUtils.merge(rolebag, localStorageLevels);
            } // 存到全局变量中


            GlobalData.getInstance().set(GameBaseDataConfig.getInstance().ROLE_BAG_KEY, rolebag); // 更新缓存

            ResourcesUtils.saveToPlatform(GameBaseDataConfig.getInstance().ROLE_BAG_PATH, rolebag);
            onComplete();
          });
        };

        return LoginBase;
      }(Component)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/main", ['./debug-view-runtime-control.ts', './ChangeCollider2DGroup.ts', './GameLevel.ts', './GameScript.ts', './MyGameController.ts', './PinAndHoles.ts', './PinScript.ts', './CoinsUpdateScript.ts', './Config.ts', './FlashScript.ts', './GMainUIRoleAndStoreScript.ts', './GameControllerEventType.ts', './GameControllerScript.ts', './HomeScript.ts', './MyLevel.ts', './MyRoleBag.ts', './PrefabsUitls.ts', './Strings.ts', './AnimateRotate.ts', './ContactDestroyOther.ts', './DraggableNode.ts', './PolygonWithCircleHolesCollider2D.ts', './PolygonWithHolesCollider2D.ts', './clipper.mjs_cjs=&original=.js', './advancingfront.mjs_cjs=&original=.js', './assert.mjs_cjs=&original=.js', './point.mjs_cjs=&original=.js', './pointerror.mjs_cjs=&original=.js', './poly2tri.mjs_cjs=&original=.js', './sweep.mjs_cjs=&original=.js', './sweepcontext.mjs_cjs=&original=.js', './triangle.mjs_cjs=&original=.js', './utils.mjs_cjs=&original=.js', './xy.mjs_cjs=&original=.js', './GButtonRewardVideoScript.ts', './GButtonScript.ts', './GButtonShareScript.ts', './btnAdapter.ts', './GDialogGridViewScript.ts', './GDialogScript.ts', './GGridViewScript.ts', './GLabelCounterTimerScript.ts', './GLabelScoreScript.ts', './GLoadingScript.ts', './updateValueLabel.ts', './GOpenOtherGame.ts', './GButtonSettingsScript.ts', './GSettingsScript.ts', './GTabCardItemScript.ts', './GTabCardScript.ts', './GTabCardTitleScript.ts', './GToastScript.ts', './RewardVideo.ts', './Share.ts', './VibrateManager.ts', './AudioManager.ts', './GlobalData.ts', './JobSystem.ts', './ResourcesUtils.ts', './StateMachine.ts', './CloudAndStorageData.ts', './GameRoot.ts', './Level.ts', './LoginBase.ts'], function () {
  return {
    setters: [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null],
    execute: function () {}
  };
});

System.register("chunks:///_virtual/MyGameController.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './GlobalData.ts', './LoginBase.ts', './GameScript.ts', './GameControllerEventType.ts', './PrefabsUitls.ts', './JobSystem.ts', './GButtonShareScript.ts', './GButtonRewardVideoScript.ts', './GLabelCounterTimerScript.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, director, Component, GlobalData, GameBaseDataConfig, GameScript, GameControllerEventType, PrefabsUtils, JobSystem, GButtonShareScript, GButtonRewardVideoScript, GLabelCounterTimerScript;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      director = module.director;
      Component = module.Component;
    }, function (module) {
      GlobalData = module.GlobalData;
    }, function (module) {
      GameBaseDataConfig = module.GameBaseDataConfig;
    }, function (module) {
      GameScript = module.default;
    }, function (module) {
      GameControllerEventType = module.GameControllerEventType;
    }, function (module) {
      PrefabsUtils = module.PrefabsUtils;
    }, function (module) {
      JobSystem = module.JobSystem;
    }, function (module) {
      GButtonShareScript = module.GButtonShareScript;
    }, function (module) {
      GButtonRewardVideoScript = module.GButtonRewardVideoScript;
    }, function (module) {
      GLabelCounterTimerScript = module.GLabelCounterTimerScript;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _dec5, _class, _class2, _descriptor, _descriptor2, _descriptor3, _descriptor4;

      cclegacy._RF.push({}, "7f7ff4L5mZB57FeHM0KFsoB", "MyGameController", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var MyGameController = exports('MyGameController', (_dec = ccclass('MyGameController'), _dec2 = property(GameScript), _dec3 = property(GButtonShareScript), _dec4 = property(GButtonRewardVideoScript), _dec5 = property(GLabelCounterTimerScript), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(MyGameController, _Component);

        function MyGameController() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "game", _descriptor, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "addMoreBollShare", _descriptor2, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "addMoreBoll", _descriptor3, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "downTimer", _descriptor4, _assertThisInitialized(_this));

          _this.gameScoreValue = 0;
          _this.gameLevel = void 0;
          return _this;
        }

        var _proto = MyGameController.prototype;

        _proto.onNewGame = function onNewGame() {
          var _this2 = this;

          var role = GlobalData.getInstance().get(GameBaseDataConfig.getInstance().ROLE_BAG_KEY).role;
          var currentLevel = GlobalData.getInstance().get(GameBaseDataConfig.getInstance().LEVEL_CURRENT_KEY);
          this.gameLevel = currentLevel; // 分享增加球

          this.addMoreBollShare.setOnClickOption({
            onShareComplete: function onShareComplete(success) {
              if (success) {
                _this2.downTimer.addTotalTime(20);
              }
            }
          }); // 激励视频增加

          this.addMoreBoll.setOnRVClickOption({
            onVideoPlayFinish: function onVideoPlayFinish(success) {
              if (success) {
                // 增加道具
                _this2.downTimer.addTotalTime(50);
              }
            }
          }); // 准备新地图

          var jobSystem = new JobSystem();
          jobSystem.addAsyncJob(function () {
            return new Promise(function (resolve) {
              PrefabsUtils.loadRoleSkinById(role.roleSkinId, function (prefabs) {
                _this2.game.pinPrefab = prefabs[0];
                console.log('[game]', 'role skin load complete', prefabs, role.roleSkinId);
                resolve();
              });
            });
          });
          jobSystem.addJob(function () {
            console.log('[game]', 'init level infos', currentLevel);

            _this2.game.setLevel(currentLevel); // 设置倒计时


            _this2.downTimer.setTotalTime(currentLevel.downTime);

            _this2.downTimer.setCountdownEndCallback(function () {
              director.emit(GameControllerEventType.GAME_FAIL);
            }); // 游戏进度


            _this2.game.setGameStateListener({
              onGameSuccess: function onGameSuccess() {
                director.emit(GameControllerEventType.GAME_SUCCESS);
              }
            });
          });
          jobSystem.runJobs();
        };

        _proto.onLoad = function onLoad() {
          director.on(GameControllerEventType.GAME_NEW, this.onNewGame, this);
        };

        _proto.update = function update(deltaTime) {};

        _proto.checkRemoveFinish = function checkRemoveFinish() {
          if (this.gameScoreValue >= this.gameLevel.target) {
            director.emit(GameControllerEventType.GAME_SUCCESS);
          }
        };

        return MyGameController;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "game", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "addMoreBollShare", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "addMoreBoll", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      }), _descriptor4 = _applyDecoratedDescriptor(_class2.prototype, "downTimer", [_dec5], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: null
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/MyLevel.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './Level.ts'], function (exports) {
  var _inheritsLoose, cclegacy, ILevel;

  return {
    setters: [function (module) {
      _inheritsLoose = module.inheritsLoose;
    }, function (module) {
      cclegacy = module.cclegacy;
    }, function (module) {
      ILevel = module.ILevel;
    }],
    execute: function () {
      cclegacy._RF.push({}, "cfcabltoElNeI481Kn8HDZN", "MyLevel", undefined);

      var LevelScene = exports('LevelScene', function LevelScene() {});
      LevelScene.NORMAL = "normal";
      var MyLevel = exports('MyLevel', /*#__PURE__*/function (_ILevel) {
        _inheritsLoose(MyLevel, _ILevel);

        function MyLevel() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _ILevel.call.apply(_ILevel, [this].concat(args)) || this;
          _this.levelIndex = 1; // 关卡的类型，可能有多种场景

          _this.levelScene = LevelScene.NORMAL;
          _this.levelPrefab = void 0;
          _this.downTime = void 0;
          _this.complete = false;
          return _this;
        }

        var _proto = MyLevel.prototype;

        _proto.fromJsonObj = function fromJsonObj(data) {
          this.levelIndex = data.levelIndex;
          this.levelPrefab = data.levelPrefab;
          this.downTime = data.downTime;
          this.complete = data.complete;

          if (data.levelScene) {
            this.levelScene = data.levelScene;
          }
        };

        _proto.getLevelUid = function getLevelUid() {
          if (this.levelScene === "normal") {
            // 兼容历史版本， 默认的id就是levelIndex
            return JSON.stringify(this.levelIndex);
          }

          return this.levelScene + " " + this.levelIndex;
        };

        _proto.copyLevelResult = function copyLevelResult(to) {
          to.complete = this.complete;
        };

        return MyLevel;
      }(ILevel));
      var MyLevelUtils = exports('MyLevelUtils', /*#__PURE__*/function () {
        function MyLevelUtils() {}

        MyLevelUtils.getFirstNotCompleteLevel = function getFirstNotCompleteLevel(levels, levelScene) {
          if (levelScene === void 0) {
            levelScene = LevelScene.NORMAL;
          }

          var sceneLevel = [];

          for (var index = 0; index < levels.length; index++) {
            var element = levels[index];

            if (element.levelScene === levelScene) {
              sceneLevel.push(element);
            }
          }

          for (var _index = 0; _index < sceneLevel.length; _index++) {
            var _element = sceneLevel[_index];

            if (_element.levelScene === levelScene) {
              if (!_element.complete) {
                return _element;
              }
            }
          } // 全部完成，返回最后


          return sceneLevel[sceneLevel.length - 1];
        };

        return MyLevelUtils;
      }());

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/MyRoleBag.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './GlobalData.ts', './ResourcesUtils.ts', './CloudAndStorageData.ts', './LoginBase.ts', './GameControllerEventType.ts'], function (exports) {
  var _inheritsLoose, _createForOfIteratorHelperLoose, cclegacy, director, GlobalData, ResourcesUtils, ICloudAndStorageData, GameBaseDataConfig, GameControllerEventType;

  return {
    setters: [function (module) {
      _inheritsLoose = module.inheritsLoose;
      _createForOfIteratorHelperLoose = module.createForOfIteratorHelperLoose;
    }, function (module) {
      cclegacy = module.cclegacy;
      director = module.director;
    }, function (module) {
      GlobalData = module.GlobalData;
    }, function (module) {
      ResourcesUtils = module.ResourcesUtils;
    }, function (module) {
      ICloudAndStorageData = module.ICloudAndStorageData;
    }, function (module) {
      GameBaseDataConfig = module.GameBaseDataConfig;
    }, function (module) {
      GameControllerEventType = module.GameControllerEventType;
    }],
    execute: function () {
      cclegacy._RF.push({}, "09f99TaYrlBj4QHfsWXHRt7", "MyRoleBag", undefined);

      var MyRoleBag = exports('MyRoleBag', /*#__PURE__*/function (_ICloudAndStorageData) {
        _inheritsLoose(MyRoleBag, _ICloudAndStorageData);

        function MyRoleBag() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _ICloudAndStorageData.call.apply(_ICloudAndStorageData, [this].concat(args)) || this;
          _this.role = void 0;
          _this.roleSkin = void 0;
          _this.weapon = void 0;
          _this.achieve = void 0;
          return _this;
        }

        var _proto = MyRoleBag.prototype; // 从json生成对象

        _proto.fromJsonObj = function fromJsonObj(data) {
          if (data.role) {
            this.role = data.role;
          }

          if (data.roleSkin) {
            this.roleSkin = data.roleSkin;
          }

          if (data.weapon) {
            this.weapon = data.weapon;
          }

          if (data.role) {
            this.achieve = data.achieve;
          }
        };

        _proto.getUid = function getUid() {
          return "MyRoleBag";
        };

        _proto.copyResult = function copyResult(to) {
          if (!to) {
            return;
          } // 一般是本地缓存覆盖远端更新的数据
          // 覆盖更新，和追加


          var pushCheckExistId = function pushCheckExistId(source, target) {
            var _loop = function _loop() {
              var item = _step.value; // 如果id相同，则更新内容

              var targetItem = target.find(function (e) {
                return e.id === item.id;
              });

              if (targetItem) {
                // 本地缓存关心的内容
                var keys = ["have"];

                for (var key in keys) {
                  targetItem[key] = item[key];
                }
              }
            };

            for (var _iterator = _createForOfIteratorHelperLoose(source), _step; !(_step = _iterator()).done;) {
              _loop();
            }
          }; // 避免把新属性也替换掉


          if (this.role && to.role) {
            // role 中所有信息都以本地为准
            for (var key in this.role) {
              to.role[key] = this.role[key];
            }
          }

          if (this.roleSkin && to.roleSkin) {
            pushCheckExistId(this.roleSkin.items, to.roleSkin.items);
          }

          if (this.weapon && to.weapon) {
            pushCheckExistId(this.weapon.items, to.weapon.items);
          }

          if (this.achieve && to.achieve) {
            pushCheckExistId(this.achieve.items, to.achieve.items);
          }
        } // 根据id获取内容
        ;

        _proto.getRoleSkinById = function getRoleSkinById(id) {
          for (var index = 0; index < this.roleSkin.items.length; index++) {
            var element = this.roleSkin.items[index];

            if (element.id === id) {
              return element;
            }
          }

          return null;
        };

        _proto.getWeaponById = function getWeaponById(id) {
          if (this.weapon) {
            for (var index = 0; index < this.weapon.items.length; index++) {
              var element = this.weapon.items[index];

              if (element.id === id) {
                return element;
              }
            }
          }

          return null;
        };

        MyRoleBag.get = function get(roleBag) {
          if (!roleBag) {
            return GlobalData.getInstance().get(GameBaseDataConfig.getInstance().ROLE_BAG_KEY);
          }

          return roleBag;
        };

        MyRoleBag.save = function save(roleBag) {
          // 保存数据
          GlobalData.getInstance().set(GameBaseDataConfig.getInstance().ROLE_BAG_KEY, roleBag);
          ResourcesUtils.saveToPlatform(GameBaseDataConfig.getInstance().ROLE_BAG_PATH, roleBag);
        };

        MyRoleBag.addCoin = function addCoin(coin, roleBag) {
          roleBag = MyRoleBag.get(roleBag);
          roleBag.role.coins += coin;
          MyRoleBag.save(roleBag);
          console.log('[game]', 'add coin, current coins', roleBag.role.coins);
          director.emit(GameControllerEventType.ROLE_COINS_UPDATE);
        }
        /**
         * 触发角色信息更新
         */
        ;

        MyRoleBag.initUpdateRoleInfos = function initUpdateRoleInfos() {
          director.emit(GameControllerEventType.ROLE_COINS_UPDATE);
        };

        return MyRoleBag;
      }(ICloudAndStorageData));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/PinAndHoles.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc'], function (exports) {
  var _createForOfIteratorHelperLoose, cclegacy, _decorator, UITransform, Rect, Vec2, CircleCollider2D, PolygonCollider2D, Intersection2D;

  return {
    setters: [function (module) {
      _createForOfIteratorHelperLoose = module.createForOfIteratorHelperLoose;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      UITransform = module.UITransform;
      Rect = module.Rect;
      Vec2 = module.Vec2;
      CircleCollider2D = module.CircleCollider2D;
      PolygonCollider2D = module.PolygonCollider2D;
      Intersection2D = module.Intersection2D;
    }],
    execute: function () {
      cclegacy._RF.push({}, "9134b4yhHpA5Ln0oXt5TRuE", "PinAndHoles", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var PinAndHoles = exports('PinAndHoles', /*#__PURE__*/function () {
        function PinAndHoles() {
          this.pinAndHoleMap = new Map();
          this.gameLevel = void 0;
        }

        var _proto = PinAndHoles.prototype;

        _proto.init = function init(gameLevel) {
          this.gameLevel = gameLevel;
          this.gameLevel.pinHoles = gameLevel.pinHoles;
          this.gameLevel.pins = gameLevel.pins;

          for (var index = 0; index < this.gameLevel.pinHoles.length; index++) {
            var pinHole = this.gameLevel.pinHoles[index];

            for (var j = 0; j < this.gameLevel.pins.length; j++) {
              var pin = this.gameLevel.pins[j];

              if (this.matchPinAndHole(pin, pinHole)) {
                this.pinAndHoleMap.set(pinHole, pin);
              }
            }
          }
        }
        /**
         * pin 和hole相交则认为是位置匹配上
         * @param pin 
         * @param pinHole 
         * @returns 
         */
        ;

        _proto.matchPinAndHole = function matchPinAndHole(pin, pinHole) {
          var box0 = pin.getComponent(UITransform).getBoundingBoxToWorld();
          var box1 = pinHole.getComponent(UITransform).getBoundingBoxToWorld();
          var intersectionRect = new Rect();
          Rect.intersection(intersectionRect, box0, box1);

          if (intersectionRect.width < 0 && intersectionRect.height < 0) {
            return false;
          }

          var intersectionArea = intersectionRect.width * intersectionRect.height;
          var area0 = box0.width * box0.height;
          var area1 = box1.width * box1.height;
          var threshold = 0.5;

          if (intersectionArea > threshold * Math.min(area0, area1)) {
            return true;
          } else {
            return false;
          }
        }
        /**
         * 获取最近的空闲的PINhole
         * @returns 
         */
        ;

        _proto.getNeseastPinHole = function getNeseastPinHole(pin) {
          for (var index = 0; index < this.gameLevel.pinHoles.length; index++) {
            var pinHole = this.gameLevel.pinHoles[index];

            if (this.matchPinAndHole(pin, pinHole)) {
              if (this.pinAndHoleMap.get(pinHole)) {
                return undefined;
              } else {
                return pinHole;
              }
            }
          }

          return undefined;
        } // pin 只能放到pinHole上
        // 一个hole只能放一个
        ;

        _proto.formatPinPos = function formatPinPos() {};

        _proto.getHoleByPin = function getHoleByPin(pin) {
          for (var _iterator = _createForOfIteratorHelperLoose(this.pinAndHoleMap.keys()), _step; !(_step = _iterator()).done;) {
            var key = _step.value;
            var savePin = this.pinAndHoleMap.get(key);

            if (savePin === pin) {
              return key;
            }
          }

          return undefined;
        }
        /**
         * 检查位置下面是否是Layer，是否有遮挡
         * @param [forseWorldPos=undefined] 一般设置为pin将要放置的位置，如果不设置则会使用pin的位置进行检查
         */
        ;

        _proto.checkHitLayer = function checkHitLayer(pin, forseWorldPos) {
          if (forseWorldPos === void 0) {
            forseWorldPos = undefined;
          }

          var pinPos = new Vec2(pin.getWorldPosition().x, pin.getWorldPosition().y);

          if (forseWorldPos) {
            pinPos = new Vec2(forseWorldPos.x, forseWorldPos.y);
          } // const pinPos = pin.getComponent(CircleCollider2D).worldPosition; // 此时物理引擎是关闭的，容易计算不准确
          // 检查的时候放宽松一些


          var pinRadius = pin.getComponent(CircleCollider2D).worldRadius * 0.8;
          var layerNodes = this.gameLevel.getAllLayerNodes();

          for (var index = 0; index < layerNodes.length; index++) {
            var nodes = layerNodes[index];

            for (var j = 0; j < nodes.length; j++) {
              var otherNode = nodes[j]; // 获取 otherNode 上的所有 PolygonCollider2D 组件

              var colliders = otherNode.getComponents(PolygonCollider2D); // 检测碰撞

              for (var i = 0; i < colliders.length; i++) {
                var collider = colliders[i];

                if (Intersection2D.polygonCircle(collider.worldPoints, pinPos, pinRadius)) {
                  // 发生了碰撞
                  // 执行相应的逻辑
                  console.log("Collision occurred!, hit the board");
                  return true;
                }
              }
            }
          }

          return false;
        }
        /**
         * 移动pin到 hole ，如果失败了会放回原地
         * @param pin 
         * @param originPos 
         */
        ;

        _proto.attempMovePin = function attempMovePin(pin, originPos) {
          // 获取当前最近的hole
          var pinHole = this.getNeseastPinHole(pin);

          if (pinHole) {
            // 如果位置有遮挡则移动失败
            if (this.checkHitLayer(pin, pinHole.getWorldPosition())) {
              return false;
            } // format位置, 在不同的node中，所以使用worldpos


            pin.setWorldPosition(pinHole.getWorldPosition()); // 更新记录
            // 清空之前的位置

            var lastPinHole = this.getHoleByPin(pin);

            if (lastPinHole) {
              this.pinAndHoleMap.set(lastPinHole, undefined);
            } // 更新当前位置


            this.pinAndHoleMap.set(pinHole, pin);
            return true;
          } else {
            console.log("pin must move to some empty pinhole!");
          }

          return false;
        };

        return PinAndHoles;
      }());

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/PinScript.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc'], function (exports) {
  var _inheritsLoose, cclegacy, _decorator, Component;

  return {
    setters: [function (module) {
      _inheritsLoose = module.inheritsLoose;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Component = module.Component;
    }],
    execute: function () {
      var _dec, _class;

      cclegacy._RF.push({}, "46523BkEcdKt6H3It3YO4tT", "PinScript", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var PinScript = exports('PinScript', (_dec = ccclass('PinScript'), _dec(_class = /*#__PURE__*/function (_Component) {
        _inheritsLoose(PinScript, _Component);

        function PinScript() {
          return _Component.apply(this, arguments) || this;
        }

        var _proto = PinScript.prototype;

        _proto.start = function start() {};

        _proto.update = function update(deltaTime) {};

        return PinScript;
      }(Component)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/point.js", ['./cjs-loader.mjs', './xy.js'], function (exports, module) {
  var loader, __cjsMetaURL$1;

  return {
    setters: [function (module) {
      loader = module.default;
    }, function (module) {
      __cjsMetaURL$1 = module.__cjsMetaURL;
    }],
    execute: function () {
      exports('default', void 0);

      var _cjsExports;

      var __cjsMetaURL = exports('__cjsMetaURL', module.meta.url);

      loader.define(__cjsMetaURL, function (exports$1, require, module, __filename, __dirname) {
        /*
         * Note
         * ====
         * the structure of this JavaScript version of poly2tri intentionally follows
         * as closely as possible the structure of the reference C++ version, to make it 
         * easier to keep the 2 versions in sync.
         */
        var xy = require('./xy'); // ------------------------------------------------------------------------Point

        /**
         * Construct a point
         * @example
         *      var point = new poly2tri.Point(150, 150);
         * @public
         * @constructor
         * @struct
         * @param {number=} x    coordinate (0 if undefined)
         * @param {number=} y    coordinate (0 if undefined)
         */


        var Point = function Point(x, y) {
          /**
           * @type {number}
           * @expose
           */
          this.x = +x || 0;
          /**
           * @type {number}
           * @expose
           */

          this.y = +y || 0; // All extra fields added to Point are prefixed with _p2t_
          // to avoid collisions if custom Point class is used.

          /**
           * The edges this point constitutes an upper ending point
           * @private
           * @type {Array.<Edge>}
           */

          this._p2t_edge_list = null;
        };
        /**
         * For pretty printing
         * @example
         *      "p=" + new poly2tri.Point(5,42)
         *      // → "p=(5;42)"
         * @returns {string} <code>"(x;y)"</code>
         */


        Point.prototype.toString = function () {
          return xy.toStringBase(this);
        };
        /**
         * JSON output, only coordinates
         * @example
         *      JSON.stringify(new poly2tri.Point(1,2))
         *      // → '{"x":1,"y":2}'
         */


        Point.prototype.toJSON = function () {
          return {
            x: this.x,
            y: this.y
          };
        };
        /**
         * Creates a copy of this Point object.
         * @return {Point} new cloned point
         */


        Point.prototype.clone = function () {
          return new Point(this.x, this.y);
        };
        /**
         * Set this Point instance to the origo. <code>(0; 0)</code>
         * @return {Point} this (for chaining)
         */


        Point.prototype.set_zero = function () {
          this.x = 0.0;
          this.y = 0.0;
          return this; // for chaining
        };
        /**
         * Set the coordinates of this instance.
         * @param {number} x   coordinate
         * @param {number} y   coordinate
         * @return {Point} this (for chaining)
         */


        Point.prototype.set = function (x, y) {
          this.x = +x || 0;
          this.y = +y || 0;
          return this; // for chaining
        };
        /**
         * Negate this Point instance. (component-wise)
         * @return {Point} this (for chaining)
         */


        Point.prototype.negate = function () {
          this.x = -this.x;
          this.y = -this.y;
          return this; // for chaining
        };
        /**
         * Add another Point object to this instance. (component-wise)
         * @param {!Point} n - Point object.
         * @return {Point} this (for chaining)
         */


        Point.prototype.add = function (n) {
          this.x += n.x;
          this.y += n.y;
          return this; // for chaining
        };
        /**
         * Subtract this Point instance with another point given. (component-wise)
         * @param {!Point} n - Point object.
         * @return {Point} this (for chaining)
         */


        Point.prototype.sub = function (n) {
          this.x -= n.x;
          this.y -= n.y;
          return this; // for chaining
        };
        /**
         * Multiply this Point instance by a scalar. (component-wise)
         * @param {number} s   scalar.
         * @return {Point} this (for chaining)
         */


        Point.prototype.mul = function (s) {
          this.x *= s;
          this.y *= s;
          return this; // for chaining
        };
        /**
         * Return the distance of this Point instance from the origo.
         * @return {number} distance
         */


        Point.prototype.length = function () {
          return Math.sqrt(this.x * this.x + this.y * this.y);
        };
        /**
         * Normalize this Point instance (as a vector).
         * @return {number} The original distance of this instance from the origo.
         */


        Point.prototype.normalize = function () {
          var len = this.length();
          this.x /= len;
          this.y /= len;
          return len;
        };
        /**
         * Test this Point object with another for equality.
         * @param {!XY} p - any "Point like" object with {x,y}
         * @return {boolean} <code>true</code> if same x and y coordinates, <code>false</code> otherwise.
         */


        Point.prototype.equals = function (p) {
          return this.x === p.x && this.y === p.y;
        }; // -----------------------------------------------------Point ("static" methods)

        /**
         * Negate a point component-wise and return the result as a new Point object.
         * @param {!XY} p - any "Point like" object with {x,y}
         * @return {Point} the resulting Point object.
         */


        Point.negate = function (p) {
          return new Point(-p.x, -p.y);
        };
        /**
         * Add two points component-wise and return the result as a new Point object.
         * @param {!XY} a - any "Point like" object with {x,y}
         * @param {!XY} b - any "Point like" object with {x,y}
         * @return {Point} the resulting Point object.
         */


        Point.add = function (a, b) {
          return new Point(a.x + b.x, a.y + b.y);
        };
        /**
         * Subtract two points component-wise and return the result as a new Point object.
         * @param {!XY} a - any "Point like" object with {x,y}
         * @param {!XY} b - any "Point like" object with {x,y}
         * @return {Point} the resulting Point object.
         */


        Point.sub = function (a, b) {
          return new Point(a.x - b.x, a.y - b.y);
        };
        /**
         * Multiply a point by a scalar and return the result as a new Point object.
         * @param {number} s - the scalar
         * @param {!XY} p - any "Point like" object with {x,y}
         * @return {Point} the resulting Point object.
         */


        Point.mul = function (s, p) {
          return new Point(s * p.x, s * p.y);
        };
        /**
         * Perform the cross product on either two points (this produces a scalar)
         * or a point and a scalar (this produces a point).
         * This function requires two parameters, either may be a Point object or a
         * number.
         * @param  {XY|number} a - Point object or scalar.
         * @param  {XY|number} b - Point object or scalar.
         * @return {Point|number} a Point object or a number, depending on the parameters.
         */


        Point.cross = function (a, b) {
          if (typeof a === 'number') {
            if (typeof b === 'number') {
              return a * b;
            } else {
              return new Point(-a * b.y, a * b.x);
            }
          } else {
            if (typeof b === 'number') {
              return new Point(b * a.y, -b * a.x);
            } else {
              return a.x * b.y - a.y * b.x;
            }
          }
        }; // -----------------------------------------------------------------"Point-Like"

        /*
         * The following functions operate on "Point" or any "Point like" object 
         * with {x,y} (duck typing).
         */


        Point.toString = xy.toString;
        Point.compare = xy.compare;
        Point.cmp = xy.compare; // backward compatibility

        Point.equals = xy.equals;
        /**
         * Peform the dot product on two vectors.
         * @public
         * @param {!XY} a - any "Point like" object with {x,y}
         * @param {!XY} b - any "Point like" object with {x,y}
         * @return {number} The dot product
         */

        Point.dot = function (a, b) {
          return a.x * b.x + a.y * b.y;
        }; // ---------------------------------------------------------Exports (public API)


        module.exports = Point; // #endregion ORIGINAL CODE

        _cjsExports = exports('default', module.exports);
      }, function () {
        return {
          './xy': __cjsMetaURL$1
        };
      });
    }
  };
});

System.register("chunks:///_virtual/pointerror.js", ['./cjs-loader.mjs', './xy.js'], function (exports, module) {
  var loader, __cjsMetaURL$1;

  return {
    setters: [function (module) {
      loader = module.default;
    }, function (module) {
      __cjsMetaURL$1 = module.__cjsMetaURL;
    }],
    execute: function () {
      exports('default', void 0);

      var _cjsExports;

      var __cjsMetaURL = exports('__cjsMetaURL', module.meta.url);

      loader.define(__cjsMetaURL, function (exports$1, require, module, __filename, __dirname) {
        /*
         * Class added in the JavaScript version (was not present in the c++ version)
         */
        var xy = require('./xy');
        /**
         * Custom exception class to indicate invalid Point values
         * @constructor
         * @public
         * @extends Error
         * @struct
         * @param {string=} message - error message
         * @param {Array.<XY>=} points - invalid points
         */


        var PointError = function PointError(message, points) {
          this.name = "PointError";
          /**
           * Invalid points
           * @public
           * @type {Array.<XY>}
           */

          this.points = points = points || [];
          /**
           * Error message
           * @public
           * @type {string}
           */

          this.message = message || "Invalid Points!";

          for (var i = 0; i < points.length; i++) {
            this.message += " " + xy.toString(points[i]);
          }
        };

        PointError.prototype = new Error();
        PointError.prototype.constructor = PointError;
        module.exports = PointError; // #endregion ORIGINAL CODE

        _cjsExports = exports('default', module.exports);
      }, function () {
        return {
          './xy': __cjsMetaURL$1
        };
      });
    }
  };
});

System.register("chunks:///_virtual/poly2tri.js", ['./cjs-loader.mjs', './pointerror.js', './point.js', './triangle.js', './sweepcontext.js', './sweep.js'], function (exports, module) {
  var loader, __cjsMetaURL$1, __cjsMetaURL$2, __cjsMetaURL$3, __cjsMetaURL$4, __cjsMetaURL$5;

  return {
    setters: [function (module) {
      loader = module.default;
    }, function (module) {
      __cjsMetaURL$1 = module.__cjsMetaURL;
    }, function (module) {
      __cjsMetaURL$2 = module.__cjsMetaURL;
    }, function (module) {
      __cjsMetaURL$3 = module.__cjsMetaURL;
    }, function (module) {
      __cjsMetaURL$4 = module.__cjsMetaURL;
    }, function (module) {
      __cjsMetaURL$5 = module.__cjsMetaURL;
    }],
    execute: function () {
      exports('default', void 0);

      var _cjsExports;

      var __cjsMetaURL = exports('__cjsMetaURL', module.meta.url);

      loader.define(__cjsMetaURL, function (exports$1, require, module, __filename, __dirname) {
        /**
         * Public API for poly2tri.js
         * @module poly2tri
         */

        /**
         * If you are not using a module system (e.g. CommonJS, RequireJS), you can access this library
         * as a global variable <code>poly2tri</code> i.e. <code>window.poly2tri</code> in a browser.
         * @name poly2tri
         * @global
         * @public
         * @type {module:poly2tri}
         */
        // var previousPoly2tri = global.poly2tri;
        // /**
        //  * For Browser + &lt;script&gt; :
        //  * reverts the {@linkcode poly2tri} global object to its previous value,
        //  * and returns a reference to the instance called.
        //  *
        //  * @example
        //  *              var p = poly2tri.noConflict();
        //  * @public
        //  * @return {module:poly2tri} instance called
        //  */
        // // (this feature is not automatically provided by browserify).
        // exports.noConflict = function() {
        //     global.poly2tri = previousPoly2tri;
        //     return exports;
        // };

        /**
         * poly2tri library version
         * @public
         * @const {string}
         */
        exports$1.VERSION = "1.5.0";
        /**
         * Exports the {@linkcode PointError} class.
         * @public
         * @typedef {PointError} module:poly2tri.PointError
         * @function
         */

        exports$1.PointError = require('./pointerror');
        /**
         * Exports the {@linkcode Point} class.
         * @public
         * @typedef {Point} module:poly2tri.Point
         * @function
         */

        exports$1.Point = require('./point');
        /**
         * Exports the {@linkcode Triangle} class.
         * @public
         * @typedef {Triangle} module:poly2tri.Triangle
         * @function
         */

        exports$1.Triangle = require('./triangle');
        /**
         * Exports the {@linkcode SweepContext} class.
         * @public
         * @typedef {SweepContext} module:poly2tri.SweepContext
         * @function
         */

        exports$1.SweepContext = require('./sweepcontext'); // Backward compatibility

        var sweep = require('./sweep');
        /**
         * @function
         * @deprecated use {@linkcode SweepContext#triangulate} instead
         */


        exports$1.triangulate = sweep.triangulate;
        /**
         * @deprecated use {@linkcode SweepContext#triangulate} instead
         * @property {function} Triangulate - use {@linkcode SweepContext#triangulate} instead
         */

        exports$1.sweep = {
          Triangulate: sweep.triangulate
        }; // #endregion ORIGINAL CODE

        _cjsExports = exports('default', module.exports);
        module.exports.VERSION;
        module.exports.PointError;
        module.exports.Point;
        module.exports.Triangle;
        module.exports.SweepContext;
        module.exports.triangulate;
        module.exports.sweep;
      }, function () {
        return {
          './pointerror': __cjsMetaURL$1,
          './point': __cjsMetaURL$2,
          './triangle': __cjsMetaURL$3,
          './sweepcontext': __cjsMetaURL$4,
          './sweep': __cjsMetaURL$5
        };
      });
    }
  };
});

System.register("chunks:///_virtual/PolygonWithCircleHolesCollider2D.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './PolygonWithHolesCollider2D.ts'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, cclegacy, _decorator, Vec2, CCFloat, PolygonWithHolesCollider2D;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Vec2 = module.Vec2;
      CCFloat = module.CCFloat;
    }, function (module) {
      PolygonWithHolesCollider2D = module.PolygonWithHolesCollider2D;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _class, _class2, _descriptor, _descriptor2, _descriptor3;

      cclegacy._RF.push({}, "300a7/sC+lBAoV4NDfSs9jv", "PolygonWithCircleHolesCollider2D", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      /**
       * 根据边框和洞，生成PolygonCollider2D
       * 会将带洞多边形三角化，然后生成多个collider
       */

      var PolygonWithCircleHolesCollider2D = exports('PolygonWithCircleHolesCollider2D', (_dec = ccclass('PolygonWithCircleHolesCollider2D'), _dec2 = property({
        type: [Vec2],
        override: true
      }), _dec3 = property([Vec2]), _dec4 = property([CCFloat]), _dec(_class = (_class2 = /*#__PURE__*/function (_PolygonWithHolesColl) {
        _inheritsLoose(PolygonWithCircleHolesCollider2D, _PolygonWithHolesColl);

        function PolygonWithCircleHolesCollider2D() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _PolygonWithHolesColl.call.apply(_PolygonWithHolesColl, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "outter", _descriptor, _assertThisInitialized(_this)); // 多个圆的中心


          _initializerDefineProperty(_this, "centerList", _descriptor2, _assertThisInitialized(_this)); // 多个圆的半径


          _initializerDefineProperty(_this, "radiusList", _descriptor3, _assertThisInitialized(_this));

          _this.circlePointNum = 4;
          return _this;
        }

        var _proto = PolygonWithCircleHolesCollider2D.prototype;

        _proto.getOutterPolygon = function getOutterPolygon() {
          return this._convertVecArrayToClipperPath(this.outter);
        };

        _proto.getClipPolygons = function getClipPolygons() {
          var res = [];

          for (var index = 0; index < this.centerList.length; index++) {
            var center = this.centerList[index];
            var radius = this.radiusList[index];
            res.push(this.generateCirclePoints(center.x, center.y, radius, this.circlePointNum));
          }

          return res;
        };

        _proto.generateCirclePoints = function generateCirclePoints(centerX, centerY, radius, numPoints) {
          if (numPoints === void 0) {
            numPoints = 180;
          }

          var points = [];
          var angleIncrement = 2 * Math.PI / numPoints;

          for (var i = 0; i < numPoints; i++) {
            // 从左上角开始, 当数量4的时候，可以得到一个朝上的正方向
            var angle = i * angleIncrement - 0.25 * Math.PI;
            var x = centerX + radius * Math.cos(angle);
            var y = centerY + radius * Math.sin(angle);
            points.push({
              X: x,
              Y: y
            });
          }

          return points;
        };

        return PolygonWithCircleHolesCollider2D;
      }(PolygonWithHolesCollider2D), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "outter", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return [];
        }
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "centerList", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return [];
        }
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "radiusList", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return [];
        }
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/PolygonWithHolesCollider2D.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './clipper.mjs_cjs=&original=.js', './poly2tri.mjs_cjs=&original=.js', './clipper.js', './poly2tri.js'], function (exports) {
  var _applyDecoratedDescriptor, _inheritsLoose, _initializerDefineProperty, _assertThisInitialized, _createForOfIteratorHelperLoose, cclegacy, _decorator, CCBoolean, Vec2, PhysicsSystem2D, EPhysics2DDrawFlags, PolygonCollider2D, Component, _cjsExports, _cjsExports$1;

  return {
    setters: [function (module) {
      _applyDecoratedDescriptor = module.applyDecoratedDescriptor;
      _inheritsLoose = module.inheritsLoose;
      _initializerDefineProperty = module.initializerDefineProperty;
      _assertThisInitialized = module.assertThisInitialized;
      _createForOfIteratorHelperLoose = module.createForOfIteratorHelperLoose;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      CCBoolean = module.CCBoolean;
      Vec2 = module.Vec2;
      PhysicsSystem2D = module.PhysicsSystem2D;
      EPhysics2DDrawFlags = module.EPhysics2DDrawFlags;
      PolygonCollider2D = module.PolygonCollider2D;
      Component = module.Component;
    }, null, null, function (module) {
      _cjsExports = module.default;
    }, function (module) {
      _cjsExports$1 = module.default;
    }],
    execute: function () {
      var _dec, _dec2, _dec3, _dec4, _class, _class2, _descriptor, _descriptor2, _descriptor3;

      cclegacy._RF.push({}, "9922fcRogtIp4dcsUJ5UmRl", "PolygonWithHolesCollider2D", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      /**
       * 根据边框和洞，生成PolygonCollider2D
       * 会将带洞多边形三角化，然后生成多个collider
       */

      var PolygonWithHolesCollider2D = exports('PolygonWithHolesCollider2D', (_dec = ccclass('PolygonWithHolesCollider2D'), _dec2 = property(CCBoolean), _dec3 = property([Vec2]), _dec4 = property([Vec2]), _dec(_class = (_class2 = /*#__PURE__*/function (_Component) {
        _inheritsLoose(PolygonWithHolesCollider2D, _Component);

        function PolygonWithHolesCollider2D() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;

          _initializerDefineProperty(_this, "debug", _descriptor, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "outter", _descriptor2, _assertThisInitialized(_this));

          _initializerDefineProperty(_this, "inner", _descriptor3, _assertThisInitialized(_this));

          return _this;
        }

        var _proto = PolygonWithHolesCollider2D.prototype;

        _proto.getOutterPolygon = function getOutterPolygon() {
          return this._convertVecArrayToClipperPath(this.outter);
        };

        _proto.getClipPolygons = function getClipPolygons() {
          var res = [];
          res.push(this._convertVecArrayToClipperPath(this.inner));
          return res;
        };

        _proto.onLoad = function onLoad() {
          if (this.debug) {
            PhysicsSystem2D.instance.debugDrawFlags = EPhysics2DDrawFlags.Shape;
          }

          this.generatePolygonCollider2D();
        };

        _proto.generatePolygonCollider2D = function generatePolygonCollider2D() {
          var _this2 = this;

          var subjectPolygon = this.getOutterPolygon();
          var clipPolygon = this.getClipPolygons(); // 创建 ClipperLib 对象

          var clipper = new _cjsExports.Clipper(); // 添加多边形路径

          clipper.AddPath(subjectPolygon, _cjsExports.PolyType.ptSubject, true);
          clipper.AddPaths(clipPolygon, _cjsExports.PolyType.ptClip, true);
          var subject_fillType = _cjsExports.PolyFillType.pftEvenOdd;
          var clip_fillType = _cjsExports.PolyFillType.pftEvenOdd;
          var solution_polytree = new _cjsExports.PolyTree(); // 取裁剪后的部分

          clipper.Execute(_cjsExports.ClipType.ctDifference, solution_polytree, subject_fillType, clip_fillType);

          var solution = _cjsExports.JS.PolyTreeToExPolygons(solution_polytree); // 处理多边形


          for (var _iterator = _createForOfIteratorHelperLoose(solution), _step; !(_step = _iterator()).done;) {
            var expolygon = _step.value;

            var countor = this._convertClipperPathToPoly2triPoint(expolygon.outer);

            var swctx = new _cjsExports$1.SweepContext(countor);
            var holes = expolygon.holes.map(function (h) {
              return _this2._convertClipperPathToPoly2triPoint(h);
            });
            swctx.addHoles(holes);

            try {
              swctx.triangulate();
              var triangles = swctx.getTriangles(); // 逐一处理三角形...

              triangles.forEach(function (tri) {
                // 每个三角形生成一个collider
                var polygonCollider2d = _this2.node.addComponent(PolygonCollider2D);

                polygonCollider2d.points = [new Vec2(tri.getPoint(0).x, tri.getPoint(0).y), new Vec2(tri.getPoint(1).x, tri.getPoint(1).y), new Vec2(tri.getPoint(2).x, tri.getPoint(2).y)];
                polygonCollider2d.friction = 0.5;
                polygonCollider2d.restitution = 0;
                polygonCollider2d.apply();
              });
            } catch (error) {
              console.error(error);
            }
          }
        };

        _proto._convertVecArrayToClipperPath = function _convertVecArrayToClipperPath(poly) {
          return poly.map(function (p) {
            return {
              X: p.x,
              Y: p.y
            };
          });
        };

        _proto._convertClipperPathToPoly2triPoint = function _convertClipperPathToPoly2triPoint(poly) {
          return poly.map(function (p) {
            return new _cjsExports$1.Point(p.X, p.Y);
          });
        };

        _proto.update = function update(deltaTime) {};

        return PolygonWithHolesCollider2D;
      }(Component), (_descriptor = _applyDecoratedDescriptor(_class2.prototype, "debug", [_dec2], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return false;
        }
      }), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "outter", [_dec3], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return [];
        }
      }), _descriptor3 = _applyDecoratedDescriptor(_class2.prototype, "inner", [_dec4], {
        configurable: true,
        enumerable: true,
        writable: true,
        initializer: function initializer() {
          return [];
        }
      })), _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/PrefabsUitls.ts", ['cc', './ResourcesUtils.ts', './Config.ts', './MyRoleBag.ts', './JobSystem.ts'], function (exports) {
  var cclegacy, ResourcesUtils, Config, MyRoleBag, JobSystem;
  return {
    setters: [function (module) {
      cclegacy = module.cclegacy;
    }, function (module) {
      ResourcesUtils = module.ResourcesUtils;
    }, function (module) {
      Config = module.Config;
    }, function (module) {
      MyRoleBag = module.MyRoleBag;
    }, function (module) {
      JobSystem = module.JobSystem;
    }],
    execute: function () {
      cclegacy._RF.push({}, "037d6Xiu+xF754C8APP5MRK", "PrefabsUitls", undefined);

      var PrefabsUtils = exports('PrefabsUtils', /*#__PURE__*/function () {
        function PrefabsUtils() {}

        PrefabsUtils.loadRoleSkinById = function loadRoleSkinById(id, onLoadComplete) {
          var skinItem = MyRoleBag.get().getRoleSkinById(id);

          if (skinItem && skinItem.prefabNames) {
            var res = [];
            var jobs = new JobSystem(); // prefab 是一个系列

            var _loop = function _loop() {
              var element = skinItem.prefabNames[index];
              jobs.addAsyncJob(function () {
                return new Promise(function (resolve) {
                  ResourcesUtils.startLoadPrefab(Config.PREFAB_PATH_ROLE_SKIN + element, function (p) {
                    res.push(p);
                    resolve();
                  });
                });
              });
            };

            for (var index = 0; index < skinItem.prefabNames.length; index++) {
              _loop();
            }

            jobs.addJob(function () {
              onLoadComplete(res);
            });
            jobs.runJobs();
          } else {
            onLoadComplete(undefined);
          }
        };

        PrefabsUtils.loadWeaponById = function loadWeaponById(id, onLoadComplete) {
          var weaponItem = MyRoleBag.get().getWeaponById(id);

          if (weaponItem) {
            ResourcesUtils.startLoadPrefab(Config.PREFAB_PATH_WEAPON + weaponItem.prefabName, onLoadComplete);
          } else {
            onLoadComplete(undefined);
          }
        };

        return PrefabsUtils;
      }());

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/ResourcesUtils.ts", ['cc', './JobSystem.ts'], function (exports) {
  var cclegacy, _decorator, assetManager, JobSystem;

  return {
    setters: [function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      assetManager = module.assetManager;
    }, function (module) {
      JobSystem = module.JobSystem;
    }],
    execute: function () {
      var _dec, _class, _class2;

      cclegacy._RF.push({}, "bec5cjaf+pLh4hgZpy5F/y/", "ResourcesUtils", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var ResourcesUtils = exports('ResourcesUtils', (_dec = ccclass('ResourcesUtils'), _dec(_class = (_class2 = /*#__PURE__*/function () {
        function ResourcesUtils() {}

        ResourcesUtils.loadBundle = function loadBundle(onComplete) {
          var jobs = new JobSystem();
          jobs.addAsyncJob(function () {
            return new Promise(function (resolve) {
              assetManager.loadBundle(ResourcesUtils.BUNDLE_NAME, function (error, bundle) {
                if (error) {
                  console.error("load loadBundle error", error);
                }

                resolve();
              });
            });
          });
          jobs.addAsyncJob(function () {
            return new Promise(function (resolve) {
              assetManager.loadBundle(ResourcesUtils.BUNDLE_NAME_UI, function (error, bundle) {
                if (error) {
                  console.error("load loadBundle error", error);
                }

                resolve();
              });
            });
          });
          jobs.addJob(function () {
            onComplete();
          });
          jobs.runJobs();
        } // start load
        ;

        ResourcesUtils.startLoadJson = function startLoadJson(path, onLoad) {
          // read json
          // console.log("load", path)
          assetManager.loadBundle(ResourcesUtils.BUNDLE_NAME, function (error, bundle) {
            if (error) {
              console.error("load loadBundle error", error);
            }

            bundle.load(path, function (error, data) {
              if (error) {
                console.error("load json complete", error, data);
              }

              onLoad(data);
            });
          });
        };

        ResourcesUtils.startLoadPrefab = function startLoadPrefab(path, onLoad) {
          // read prefab
          // console.log("load", path)
          assetManager.loadBundle(ResourcesUtils.BUNDLE_NAME, function (error, bundle) {
            if (error) {
              console.error("load loadBundle error", error);
            }

            bundle.load(path, function (error, data) {
              if (error) {
                console.error("load prefab complete", error, data);
              }

              onLoad(data);
            });
          });
        }
        /**
         * 保存到小程序的路径
         * @param path 
         * @param data 
         */
        ;

        ResourcesUtils.saveToPlatform = function saveToPlatform(path, data) {
          localStorage.setItem(path, JSON.stringify(data));
        }
        /**
         * 读取数据
         * @param path 
         * @param data 
         */
        ;

        ResourcesUtils.getFromPlatform = function getFromPlatform(path) {
          var res = localStorage.getItem(path);
          return res;
        }
        /**
         * 读取本地音视频等资源
         * @param url 
         * @param type 
         * @param cb 
         */
        ;

        ResourcesUtils.loadRes = function loadRes(bundleName, url, type, cb) {
          assetManager.loadBundle(bundleName, function (error, bundle) {
            if (error) {
              console.error("load loadBundle error", error);
            }

            if (type) {
              bundle.load(url, type, function (err, res) {
                if (err) {
                  console.error(err.message || err);

                  if (cb) {
                    cb(err, res);
                  }

                  return;
                }

                if (cb) {
                  cb(err, res);
                }
              });
            } else {
              bundle.load(url, function (err, res) {
                if (err) {
                  console.error(err.message || err);

                  if (cb) {
                    cb(err, res);
                  }

                  return;
                }

                if (cb) {
                  cb(err, res);
                }
              });
            }
          });
        };

        return ResourcesUtils;
      }(), _class2.BUNDLE_NAME = "resources", _class2.BUNDLE_NAME_UI = "ui_resources", _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/RewardVideo.ts", ['cc'], function (exports) {
  var cclegacy;
  return {
    setters: [function (module) {
      cclegacy = module.cclegacy;
    }],
    execute: function () {
      cclegacy._RF.push({}, "8cf6eTupSlKGqOg+LmREAn/", "RewardVideo", undefined);

      var RewardVideo = exports('RewardVideo', /*#__PURE__*/function () {
        function RewardVideo() {}

        var _proto = RewardVideo.prototype;

        _proto.show = function show(onCompete) {
          {
            console.log('激励视频 广告显示失败');
            onCompete(true);
          }
        };

        return RewardVideo;
      }());

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/Share.ts", ['cc'], function (exports) {
  var cclegacy;
  return {
    setters: [function (module) {
      cclegacy = module.cclegacy;
    }],
    execute: function () {
      cclegacy._RF.push({}, "d20596iLL1CqqmdfWEL7tzP", "Share", undefined);

      var Share = exports('Share', /*#__PURE__*/function () {
        function Share() {} // 允许分享给朋友和朋友圈，不打开，默认是不允许分享


        Share.showShareMenu = function showShareMenu() {} // 分享
        ;

        var _proto = Share.prototype;

        _proto.shareMessage = function shareMessage(message, onCompete) {
          {
            console.log("非wx场景");

            if (onCompete) {
              onCompete(true);
            }
          }
        } // 打开其他小程序
        ;

        _proto.openOtherGame = function openOtherGame(appid, onCompete) {
          {
            console.log("非wx场景. 跳转失败");

            if (onCompete) {
              onCompete(false);
            }
          }
        };

        return Share;
      }());

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/StateMachine.ts", ['cc'], function (exports) {
  var cclegacy;
  return {
    setters: [function (module) {
      cclegacy = module.cclegacy;
    }],
    execute: function () {
      cclegacy._RF.push({}, "fae2e0WAlFIEq33P4fT570e", "StateMachine", undefined);

      var IEnterData = exports('IEnterData', function IEnterData() {
        this.from = void 0;
      });
      var StateWithMachine = exports('StateWithMachine', /*#__PURE__*/function () {
        function StateWithMachine(stateMachine) {
          this.stateMachine = void 0;
          this.stateMachine = stateMachine;
        }

        var _proto = StateWithMachine.prototype;

        _proto.canTransitionTo = function canTransitionTo(state) {
          return false;
        };

        _proto.onEnter = function onEnter(data) {};

        _proto.onLeave = function onLeave() {};

        _proto.getName = function getName() {
          return 'StateWithMachine';
        };

        return StateWithMachine;
      }());
      var StateMachine = exports('StateMachine', /*#__PURE__*/function () {
        function StateMachine(initialState) {
          this.currentState = void 0;
          this.queue = void 0;
          this.isProcessingQueue = void 0;
          this.queue = [];
          this.isProcessingQueue = false;
          this.currentState = initialState;
          initialState.onEnter({
            from: null
          });
        }

        var _proto2 = StateMachine.prototype;

        _proto2.transitionTo = function transitionTo(state, data) {
          this.queue.push({
            state: state,
            data: data
          }); // this.processQueue();
        };

        _proto2.processQueue = function processQueue() {
          if (this.isProcessingQueue) {
            return;
          }

          this.isProcessingQueue = true;

          while (this.queue.length > 0) {
            var _this$queue$shift = this.queue.shift(),
                _state = _this$queue$shift.state,
                _data = _this$queue$shift.data;

            if (this.currentState.canTransitionTo(_state)) {
              _data.from = this.currentState;
              this.currentState.onLeave();
              this.currentState = _state;
              console.log("[state] transition from " + _data.from.getName() + " to " + _state.getName());
              this.currentState.onEnter(_data);
            } else {
              console.log("[state] Cannot transition from " + this.currentState.getName() + " to " + _state.getName());
            }
          }

          this.isProcessingQueue = false;
        };

        _proto2.getCurrentState = function getCurrentState() {
          return this.currentState;
        };

        return StateMachine;
      }());

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/Strings.ts", ['cc'], function (exports) {
  var cclegacy;
  return {
    setters: [function (module) {
      cclegacy = module.cclegacy;
    }],
    execute: function () {
      cclegacy._RF.push({}, "0c964yAl9VAureshcttfKqB", "Strings", undefined);

      var Strings = exports('Strings', function Strings() {});
      Strings.SHARE_MESSAGE = "来一起玩吧！";
      Strings.SHARE_FAILED = "分享失败, 没有奖励！";

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/sweep.js", ['./cjs-loader.mjs', './assert.js', './pointerror.js', './triangle.js', './advancingfront.js', './utils.js'], function (exports, module) {
  var loader, __cjsMetaURL$1, __cjsMetaURL$2, __cjsMetaURL$3, __cjsMetaURL$4, __cjsMetaURL$5;

  return {
    setters: [function (module) {
      loader = module.default;
    }, function (module) {
      __cjsMetaURL$1 = module.__cjsMetaURL;
    }, function (module) {
      __cjsMetaURL$2 = module.__cjsMetaURL;
    }, function (module) {
      __cjsMetaURL$3 = module.__cjsMetaURL;
    }, function (module) {
      __cjsMetaURL$4 = module.__cjsMetaURL;
    }, function (module) {
      __cjsMetaURL$5 = module.__cjsMetaURL;
    }],
    execute: function () {
      exports('default', void 0);

      var _cjsExports;

      var __cjsMetaURL = exports('__cjsMetaURL', module.meta.url);

      loader.define(__cjsMetaURL, function (exports$1, require, module, __filename, __dirname) {
        /**
         * This 'Sweep' module is present in order to keep this JavaScript version
         * as close as possible to the reference C++ version, even though almost all
         * functions could be declared as methods on the {@linkcode module:sweepcontext~SweepContext} object.
         * @module
         * @private
         */

        /*
         * Note
         * ====
         * the structure of this JavaScript version of poly2tri intentionally follows
         * as closely as possible the structure of the reference C++ version, to make it 
         * easier to keep the 2 versions in sync.
         */
        var assert = require('./assert');

        var PointError = require('./pointerror');

        var Triangle = require('./triangle');

        var Node = require('./advancingfront').Node; // ------------------------------------------------------------------------utils


        var utils = require('./utils');
        /** @const */


        var EPSILON = utils.EPSILON;
        /** @const */

        var Orientation = utils.Orientation;
        /** @const */

        var orient2d = utils.orient2d;
        /** @const */

        var inScanArea = utils.inScanArea;
        /** @const */

        var isAngleObtuse = utils.isAngleObtuse; // ------------------------------------------------------------------------Sweep

        /**
         * Triangulate the polygon with holes and Steiner points.
         * Do this AFTER you've added the polyline, holes, and Steiner points
         * @private
         * @param {!SweepContext} tcx - SweepContext object
         */

        function triangulate(tcx) {
          tcx.initTriangulation();
          tcx.createAdvancingFront(); // Sweep points; build mesh

          sweepPoints(tcx); // Clean up

          finalizationPolygon(tcx);
        }
        /**
         * Start sweeping the Y-sorted point set from bottom to top
         * @param {!SweepContext} tcx - SweepContext object
         */


        function sweepPoints(tcx) {
          var i,
              len = tcx.pointCount();

          for (i = 1; i < len; ++i) {
            var point = tcx.getPoint(i);
            var node = pointEvent(tcx, point);
            var edges = point._p2t_edge_list;

            for (var j = 0; edges && j < edges.length; ++j) {
              edgeEventByEdge(tcx, edges[j], node);
            }
          }
        }
        /**
         * @param {!SweepContext} tcx - SweepContext object
         */


        function finalizationPolygon(tcx) {
          // Get an Internal triangle to start with
          var t = tcx.front().head().next.triangle;
          var p = tcx.front().head().next.point;

          while (!t.getConstrainedEdgeCW(p)) {
            t = t.neighborCCW(p);
          } // Collect interior triangles constrained by edges


          tcx.meshClean(t);
        }
        /**
         * Find closes node to the left of the new point and
         * create a new triangle. If needed new holes and basins
         * will be filled to.
         * @param {!SweepContext} tcx - SweepContext object
         * @param {!XY} point   Point
         */


        function pointEvent(tcx, point) {
          var node = tcx.locateNode(point);
          var new_node = newFrontTriangle(tcx, point, node); // Only need to check +epsilon since point never have smaller
          // x value than node due to how we fetch nodes from the front

          if (point.x <= node.point.x + EPSILON) {
            fill(tcx, node);
          } //tcx.AddNode(new_node);


          fillAdvancingFront(tcx, new_node);
          return new_node;
        }

        function edgeEventByEdge(tcx, edge, node) {
          tcx.edge_event.constrained_edge = edge;
          tcx.edge_event.right = edge.p.x > edge.q.x;

          if (isEdgeSideOfTriangle(node.triangle, edge.p, edge.q)) {
            return;
          } // For now we will do all needed filling
          // TODO: integrate with flip process might give some better performance
          //       but for now this avoid the issue with cases that needs both flips and fills


          fillEdgeEvent(tcx, edge, node);
          edgeEventByPoints(tcx, edge.p, edge.q, node.triangle, edge.q);
        }

        function edgeEventByPoints(tcx, ep, eq, triangle, point) {
          if (isEdgeSideOfTriangle(triangle, ep, eq)) {
            return;
          }

          var p1 = triangle.pointCCW(point);
          var o1 = orient2d(eq, p1, ep);

          if (o1 === Orientation.COLLINEAR) {
            // TODO integrate here changes from C++ version
            // (C++ repo revision 09880a869095 dated March 8, 2011)
            throw new PointError('poly2tri EdgeEvent: Collinear not supported!', [eq, p1, ep]);
          }

          var p2 = triangle.pointCW(point);
          var o2 = orient2d(eq, p2, ep);

          if (o2 === Orientation.COLLINEAR) {
            // TODO integrate here changes from C++ version
            // (C++ repo revision 09880a869095 dated March 8, 2011)
            throw new PointError('poly2tri EdgeEvent: Collinear not supported!', [eq, p2, ep]);
          }

          if (o1 === o2) {
            // Need to decide if we are rotating CW or CCW to get to a triangle
            // that will cross edge
            if (o1 === Orientation.CW) {
              triangle = triangle.neighborCCW(point);
            } else {
              triangle = triangle.neighborCW(point);
            }

            edgeEventByPoints(tcx, ep, eq, triangle, point);
          } else {
            // This triangle crosses constraint so lets flippin start!
            flipEdgeEvent(tcx, ep, eq, triangle, point);
          }
        }

        function isEdgeSideOfTriangle(triangle, ep, eq) {
          var index = triangle.edgeIndex(ep, eq);

          if (index !== -1) {
            triangle.markConstrainedEdgeByIndex(index);
            var t = triangle.getNeighbor(index);

            if (t) {
              t.markConstrainedEdgeByPoints(ep, eq);
            }

            return true;
          }

          return false;
        }
        /**
         * Creates a new front triangle and legalize it
         * @param {!SweepContext} tcx - SweepContext object
         */


        function newFrontTriangle(tcx, point, node) {
          var triangle = new Triangle(point, node.point, node.next.point);
          triangle.markNeighbor(node.triangle);
          tcx.addToMap(triangle);
          var new_node = new Node(point);
          new_node.next = node.next;
          new_node.prev = node;
          node.next.prev = new_node;
          node.next = new_node;

          if (!legalize(tcx, triangle)) {
            tcx.mapTriangleToNodes(triangle);
          }

          return new_node;
        }
        /**
         * Adds a triangle to the advancing front to fill a hole.
         * @param {!SweepContext} tcx - SweepContext object
         * @param node - middle node, that is the bottom of the hole
         */


        function fill(tcx, node) {
          var triangle = new Triangle(node.prev.point, node.point, node.next.point); // TODO: should copy the constrained_edge value from neighbor triangles
          //       for now constrained_edge values are copied during the legalize

          triangle.markNeighbor(node.prev.triangle);
          triangle.markNeighbor(node.triangle);
          tcx.addToMap(triangle); // Update the advancing front

          node.prev.next = node.next;
          node.next.prev = node.prev; // If it was legalized the triangle has already been mapped

          if (!legalize(tcx, triangle)) {
            tcx.mapTriangleToNodes(triangle);
          } //tcx.removeNode(node);

        }
        /**
         * Fills holes in the Advancing Front
         * @param {!SweepContext} tcx - SweepContext object
         */


        function fillAdvancingFront(tcx, n) {
          // Fill right holes
          var node = n.next;

          while (node.next) {
            // TODO integrate here changes from C++ version
            // (C++ repo revision acf81f1f1764 dated April 7, 2012)
            if (isAngleObtuse(node.point, node.next.point, node.prev.point)) {
              break;
            }

            fill(tcx, node);
            node = node.next;
          } // Fill left holes


          node = n.prev;

          while (node.prev) {
            // TODO integrate here changes from C++ version
            // (C++ repo revision acf81f1f1764 dated April 7, 2012)
            if (isAngleObtuse(node.point, node.next.point, node.prev.point)) {
              break;
            }

            fill(tcx, node);
            node = node.prev;
          } // Fill right basins


          if (n.next && n.next.next) {
            if (isBasinAngleRight(n)) {
              fillBasin(tcx, n);
            }
          }
        }
        /**
         * The basin angle is decided against the horizontal line [1,0].
         * @param {Node} node
         * @return {boolean} true if angle < 3*π/4
         */


        function isBasinAngleRight(node) {
          var ax = node.point.x - node.next.next.point.x;
          var ay = node.point.y - node.next.next.point.y;
          assert(ay >= 0, "unordered y");
          return ax >= 0 || Math.abs(ax) < ay;
        }
        /**
         * Returns true if triangle was legalized
         * @param {!SweepContext} tcx - SweepContext object
         * @return {boolean}
         */


        function legalize(tcx, t) {
          // To legalize a triangle we start by finding if any of the three edges
          // violate the Delaunay condition
          for (var i = 0; i < 3; ++i) {
            if (t.delaunay_edge[i]) {
              continue;
            }

            var ot = t.getNeighbor(i);

            if (ot) {
              var p = t.getPoint(i);
              var op = ot.oppositePoint(t, p);
              var oi = ot.index(op); // If this is a Constrained Edge or a Delaunay Edge(only during recursive legalization)
              // then we should not try to legalize

              if (ot.constrained_edge[oi] || ot.delaunay_edge[oi]) {
                t.constrained_edge[i] = ot.constrained_edge[oi];
                continue;
              }

              var inside = inCircle(p, t.pointCCW(p), t.pointCW(p), op);

              if (inside) {
                // Lets mark this shared edge as Delaunay
                t.delaunay_edge[i] = true;
                ot.delaunay_edge[oi] = true; // Lets rotate shared edge one vertex CW to legalize it

                rotateTrianglePair(t, p, ot, op); // We now got one valid Delaunay Edge shared by two triangles
                // This gives us 4 new edges to check for Delaunay
                // Make sure that triangle to node mapping is done only one time for a specific triangle

                var not_legalized = !legalize(tcx, t);

                if (not_legalized) {
                  tcx.mapTriangleToNodes(t);
                }

                not_legalized = !legalize(tcx, ot);

                if (not_legalized) {
                  tcx.mapTriangleToNodes(ot);
                } // Reset the Delaunay edges, since they only are valid Delaunay edges
                // until we add a new triangle or point.
                // XXX: need to think about this. Can these edges be tried after we
                //      return to previous recursive level?


                t.delaunay_edge[i] = false;
                ot.delaunay_edge[oi] = false; // If triangle have been legalized no need to check the other edges since
                // the recursive legalization will handles those so we can end here.

                return true;
              }
            }
          }

          return false;
        }
        /**
         * <b>Requirement</b>:<br>
         * 1. a,b and c form a triangle.<br>
         * 2. a and d is know to be on opposite side of bc<br>
         * <pre>
         *                a
         *                +
         *               / \
         *              /   \
         *            b/     \c
         *            +-------+
         *           /    d    \
         *          /           \
         * </pre>
         * <b>Fact</b>: d has to be in area B to have a chance to be inside the circle formed by
         *  a,b and c<br>
         *  d is outside B if orient2d(a,b,d) or orient2d(c,a,d) is CW<br>
         *  This preknowledge gives us a way to optimize the incircle test
         * @param pa - triangle point, opposite d
         * @param pb - triangle point
         * @param pc - triangle point
         * @param pd - point opposite a
         * @return {boolean} true if d is inside circle, false if on circle edge
         */


        function inCircle(pa, pb, pc, pd) {
          var adx = pa.x - pd.x;
          var ady = pa.y - pd.y;
          var bdx = pb.x - pd.x;
          var bdy = pb.y - pd.y;
          var adxbdy = adx * bdy;
          var bdxady = bdx * ady;
          var oabd = adxbdy - bdxady;

          if (oabd <= 0) {
            return false;
          }

          var cdx = pc.x - pd.x;
          var cdy = pc.y - pd.y;
          var cdxady = cdx * ady;
          var adxcdy = adx * cdy;
          var ocad = cdxady - adxcdy;

          if (ocad <= 0) {
            return false;
          }

          var bdxcdy = bdx * cdy;
          var cdxbdy = cdx * bdy;
          var alift = adx * adx + ady * ady;
          var blift = bdx * bdx + bdy * bdy;
          var clift = cdx * cdx + cdy * cdy;
          var det = alift * (bdxcdy - cdxbdy) + blift * ocad + clift * oabd;
          return det > 0;
        }
        /**
         * Rotates a triangle pair one vertex CW
         *<pre>
         *       n2                    n2
         *  P +-----+             P +-----+
         *    | t  /|               |\  t |
         *    |   / |               | \   |
         *  n1|  /  |n3           n1|  \  |n3
         *    | /   |    after CW   |   \ |
         *    |/ oT |               | oT \|
         *    +-----+ oP            +-----+
         *       n4                    n4
         * </pre>
         */


        function rotateTrianglePair(t, p, ot, op) {
          var n1, n2, n3, n4;
          n1 = t.neighborCCW(p);
          n2 = t.neighborCW(p);
          n3 = ot.neighborCCW(op);
          n4 = ot.neighborCW(op);
          var ce1, ce2, ce3, ce4;
          ce1 = t.getConstrainedEdgeCCW(p);
          ce2 = t.getConstrainedEdgeCW(p);
          ce3 = ot.getConstrainedEdgeCCW(op);
          ce4 = ot.getConstrainedEdgeCW(op);
          var de1, de2, de3, de4;
          de1 = t.getDelaunayEdgeCCW(p);
          de2 = t.getDelaunayEdgeCW(p);
          de3 = ot.getDelaunayEdgeCCW(op);
          de4 = ot.getDelaunayEdgeCW(op);
          t.legalize(p, op);
          ot.legalize(op, p); // Remap delaunay_edge

          ot.setDelaunayEdgeCCW(p, de1);
          t.setDelaunayEdgeCW(p, de2);
          t.setDelaunayEdgeCCW(op, de3);
          ot.setDelaunayEdgeCW(op, de4); // Remap constrained_edge

          ot.setConstrainedEdgeCCW(p, ce1);
          t.setConstrainedEdgeCW(p, ce2);
          t.setConstrainedEdgeCCW(op, ce3);
          ot.setConstrainedEdgeCW(op, ce4); // Remap neighbors
          // XXX: might optimize the markNeighbor by keeping track of
          //      what side should be assigned to what neighbor after the
          //      rotation. Now mark neighbor does lots of testing to find
          //      the right side.

          t.clearNeighbors();
          ot.clearNeighbors();

          if (n1) {
            ot.markNeighbor(n1);
          }

          if (n2) {
            t.markNeighbor(n2);
          }

          if (n3) {
            t.markNeighbor(n3);
          }

          if (n4) {
            ot.markNeighbor(n4);
          }

          t.markNeighbor(ot);
        }
        /**
         * Fills a basin that has formed on the Advancing Front to the right
         * of given node.<br>
         * First we decide a left,bottom and right node that forms the
         * boundaries of the basin. Then we do a reqursive fill.
         *
         * @param {!SweepContext} tcx - SweepContext object
         * @param node - starting node, this or next node will be left node
         */


        function fillBasin(tcx, node) {
          if (orient2d(node.point, node.next.point, node.next.next.point) === Orientation.CCW) {
            tcx.basin.left_node = node.next.next;
          } else {
            tcx.basin.left_node = node.next;
          } // Find the bottom and right node


          tcx.basin.bottom_node = tcx.basin.left_node;

          while (tcx.basin.bottom_node.next && tcx.basin.bottom_node.point.y >= tcx.basin.bottom_node.next.point.y) {
            tcx.basin.bottom_node = tcx.basin.bottom_node.next;
          }

          if (tcx.basin.bottom_node === tcx.basin.left_node) {
            // No valid basin
            return;
          }

          tcx.basin.right_node = tcx.basin.bottom_node;

          while (tcx.basin.right_node.next && tcx.basin.right_node.point.y < tcx.basin.right_node.next.point.y) {
            tcx.basin.right_node = tcx.basin.right_node.next;
          }

          if (tcx.basin.right_node === tcx.basin.bottom_node) {
            // No valid basins
            return;
          }

          tcx.basin.width = tcx.basin.right_node.point.x - tcx.basin.left_node.point.x;
          tcx.basin.left_highest = tcx.basin.left_node.point.y > tcx.basin.right_node.point.y;
          fillBasinReq(tcx, tcx.basin.bottom_node);
        }
        /**
         * Recursive algorithm to fill a Basin with triangles
         *
         * @param {!SweepContext} tcx - SweepContext object
         * @param node - bottom_node
         */


        function fillBasinReq(tcx, node) {
          // if shallow stop filling
          if (isShallow(tcx, node)) {
            return;
          }

          fill(tcx, node);
          var o;

          if (node.prev === tcx.basin.left_node && node.next === tcx.basin.right_node) {
            return;
          } else if (node.prev === tcx.basin.left_node) {
            o = orient2d(node.point, node.next.point, node.next.next.point);

            if (o === Orientation.CW) {
              return;
            }

            node = node.next;
          } else if (node.next === tcx.basin.right_node) {
            o = orient2d(node.point, node.prev.point, node.prev.prev.point);

            if (o === Orientation.CCW) {
              return;
            }

            node = node.prev;
          } else {
            // Continue with the neighbor node with lowest Y value
            if (node.prev.point.y < node.next.point.y) {
              node = node.prev;
            } else {
              node = node.next;
            }
          }

          fillBasinReq(tcx, node);
        }

        function isShallow(tcx, node) {
          var height;

          if (tcx.basin.left_highest) {
            height = tcx.basin.left_node.point.y - node.point.y;
          } else {
            height = tcx.basin.right_node.point.y - node.point.y;
          } // if shallow stop filling


          if (tcx.basin.width > height) {
            return true;
          }

          return false;
        }

        function fillEdgeEvent(tcx, edge, node) {
          if (tcx.edge_event.right) {
            fillRightAboveEdgeEvent(tcx, edge, node);
          } else {
            fillLeftAboveEdgeEvent(tcx, edge, node);
          }
        }

        function fillRightAboveEdgeEvent(tcx, edge, node) {
          while (node.next.point.x < edge.p.x) {
            // Check if next node is below the edge
            if (orient2d(edge.q, node.next.point, edge.p) === Orientation.CCW) {
              fillRightBelowEdgeEvent(tcx, edge, node);
            } else {
              node = node.next;
            }
          }
        }

        function fillRightBelowEdgeEvent(tcx, edge, node) {
          if (node.point.x < edge.p.x) {
            if (orient2d(node.point, node.next.point, node.next.next.point) === Orientation.CCW) {
              // Concave
              fillRightConcaveEdgeEvent(tcx, edge, node);
            } else {
              // Convex
              fillRightConvexEdgeEvent(tcx, edge, node); // Retry this one

              fillRightBelowEdgeEvent(tcx, edge, node);
            }
          }
        }

        function fillRightConcaveEdgeEvent(tcx, edge, node) {
          fill(tcx, node.next);

          if (node.next.point !== edge.p) {
            // Next above or below edge?
            if (orient2d(edge.q, node.next.point, edge.p) === Orientation.CCW) {
              // Below
              if (orient2d(node.point, node.next.point, node.next.next.point) === Orientation.CCW) {
                // Next is concave
                fillRightConcaveEdgeEvent(tcx, edge, node);
              }
            }
          }
        }

        function fillRightConvexEdgeEvent(tcx, edge, node) {
          // Next concave or convex?
          if (orient2d(node.next.point, node.next.next.point, node.next.next.next.point) === Orientation.CCW) {
            // Concave
            fillRightConcaveEdgeEvent(tcx, edge, node.next);
          } else {
            // Convex
            // Next above or below edge?
            if (orient2d(edge.q, node.next.next.point, edge.p) === Orientation.CCW) {
              // Below
              fillRightConvexEdgeEvent(tcx, edge, node.next);
            }
          }
        }

        function fillLeftAboveEdgeEvent(tcx, edge, node) {
          while (node.prev.point.x > edge.p.x) {
            // Check if next node is below the edge
            if (orient2d(edge.q, node.prev.point, edge.p) === Orientation.CW) {
              fillLeftBelowEdgeEvent(tcx, edge, node);
            } else {
              node = node.prev;
            }
          }
        }

        function fillLeftBelowEdgeEvent(tcx, edge, node) {
          if (node.point.x > edge.p.x) {
            if (orient2d(node.point, node.prev.point, node.prev.prev.point) === Orientation.CW) {
              // Concave
              fillLeftConcaveEdgeEvent(tcx, edge, node);
            } else {
              // Convex
              fillLeftConvexEdgeEvent(tcx, edge, node); // Retry this one

              fillLeftBelowEdgeEvent(tcx, edge, node);
            }
          }
        }

        function fillLeftConvexEdgeEvent(tcx, edge, node) {
          // Next concave or convex?
          if (orient2d(node.prev.point, node.prev.prev.point, node.prev.prev.prev.point) === Orientation.CW) {
            // Concave
            fillLeftConcaveEdgeEvent(tcx, edge, node.prev);
          } else {
            // Convex
            // Next above or below edge?
            if (orient2d(edge.q, node.prev.prev.point, edge.p) === Orientation.CW) {
              // Below
              fillLeftConvexEdgeEvent(tcx, edge, node.prev);
            }
          }
        }

        function fillLeftConcaveEdgeEvent(tcx, edge, node) {
          fill(tcx, node.prev);

          if (node.prev.point !== edge.p) {
            // Next above or below edge?
            if (orient2d(edge.q, node.prev.point, edge.p) === Orientation.CW) {
              // Below
              if (orient2d(node.point, node.prev.point, node.prev.prev.point) === Orientation.CW) {
                // Next is concave
                fillLeftConcaveEdgeEvent(tcx, edge, node);
              }
            }
          }
        }

        function flipEdgeEvent(tcx, ep, eq, t, p) {
          var ot = t.neighborAcross(p);
          assert(ot, "FLIP failed due to missing triangle!");
          var op = ot.oppositePoint(t, p); // Additional check from Java version (see issue #88)

          if (t.getConstrainedEdgeAcross(p)) {
            var index = t.index(p);
            throw new PointError("poly2tri Intersecting Constraints", [p, op, t.getPoint((index + 1) % 3), t.getPoint((index + 2) % 3)]);
          }

          if (inScanArea(p, t.pointCCW(p), t.pointCW(p), op)) {
            // Lets rotate shared edge one vertex CW
            rotateTrianglePair(t, p, ot, op);
            tcx.mapTriangleToNodes(t);
            tcx.mapTriangleToNodes(ot); // XXX: in the original C++ code for the next 2 lines, we are
            // comparing point values (and not pointers). In this JavaScript
            // code, we are comparing point references (pointers). This works
            // because we can't have 2 different points with the same values.
            // But to be really equivalent, we should use "Point.equals" here.

            if (p === eq && op === ep) {
              if (eq === tcx.edge_event.constrained_edge.q && ep === tcx.edge_event.constrained_edge.p) {
                t.markConstrainedEdgeByPoints(ep, eq);
                ot.markConstrainedEdgeByPoints(ep, eq);
                legalize(tcx, t);
                legalize(tcx, ot);
              }
            } else {
              var o = orient2d(eq, op, ep);
              t = nextFlipTriangle(tcx, o, t, ot, p, op);
              flipEdgeEvent(tcx, ep, eq, t, p);
            }
          } else {
            var newP = nextFlipPoint(ep, eq, ot, op);
            flipScanEdgeEvent(tcx, ep, eq, t, ot, newP);
            edgeEventByPoints(tcx, ep, eq, t, p);
          }
        }
        /**
         * After a flip we have two triangles and know that only one will still be
         * intersecting the edge. So decide which to contiune with and legalize the other
         *
         * @param {!SweepContext} tcx - SweepContext object
         * @param o - should be the result of an orient2d( eq, op, ep )
         * @param t - triangle 1
         * @param ot - triangle 2
         * @param p - a point shared by both triangles
         * @param op - another point shared by both triangles
         * @return returns the triangle still intersecting the edge
         */


        function nextFlipTriangle(tcx, o, t, ot, p, op) {
          var edge_index;

          if (o === Orientation.CCW) {
            // ot is not crossing edge after flip
            edge_index = ot.edgeIndex(p, op);
            ot.delaunay_edge[edge_index] = true;
            legalize(tcx, ot);
            ot.clearDelaunayEdges();
            return t;
          } // t is not crossing edge after flip


          edge_index = t.edgeIndex(p, op);
          t.delaunay_edge[edge_index] = true;
          legalize(tcx, t);
          t.clearDelaunayEdges();
          return ot;
        }
        /**
         * When we need to traverse from one triangle to the next we need
         * the point in current triangle that is the opposite point to the next
         * triangle.
         */


        function nextFlipPoint(ep, eq, ot, op) {
          var o2d = orient2d(eq, op, ep);

          if (o2d === Orientation.CW) {
            // Right
            return ot.pointCCW(op);
          } else if (o2d === Orientation.CCW) {
            // Left
            return ot.pointCW(op);
          } else {
            throw new PointError("poly2tri [Unsupported] nextFlipPoint: opposing point on constrained edge!", [eq, op, ep]);
          }
        }
        /**
         * Scan part of the FlipScan algorithm<br>
         * When a triangle pair isn't flippable we will scan for the next
         * point that is inside the flip triangle scan area. When found
         * we generate a new flipEdgeEvent
         *
         * @param {!SweepContext} tcx - SweepContext object
         * @param ep - last point on the edge we are traversing
         * @param eq - first point on the edge we are traversing
         * @param {!Triangle} flip_triangle - the current triangle sharing the point eq with edge
         * @param t
         * @param p
         */


        function flipScanEdgeEvent(tcx, ep, eq, flip_triangle, t, p) {
          var ot = t.neighborAcross(p);
          assert(ot, "FLIP failed due to missing triangle");
          var op = ot.oppositePoint(t, p);

          if (inScanArea(eq, flip_triangle.pointCCW(eq), flip_triangle.pointCW(eq), op)) {
            // flip with new edge op.eq
            flipEdgeEvent(tcx, eq, op, ot, op);
          } else {
            var newP = nextFlipPoint(ep, eq, ot, op);
            flipScanEdgeEvent(tcx, ep, eq, flip_triangle, ot, newP);
          }
        } // ----------------------------------------------------------------------Exports


        exports$1.triangulate = triangulate; // #endregion ORIGINAL CODE

        _cjsExports = exports('default', module.exports);
        module.exports.triangulate;
      }, function () {
        return {
          './assert': __cjsMetaURL$1,
          './pointerror': __cjsMetaURL$2,
          './triangle': __cjsMetaURL$3,
          './advancingfront': __cjsMetaURL$4,
          './utils': __cjsMetaURL$5
        };
      });
    }
  };
});

System.register("chunks:///_virtual/sweepcontext.js", ['./cjs-loader.mjs', './pointerror.js', './point.js', './triangle.js', './sweep.js', './advancingfront.js'], function (exports, module) {
  var loader, __cjsMetaURL$1, __cjsMetaURL$2, __cjsMetaURL$3, __cjsMetaURL$4, __cjsMetaURL$5;

  return {
    setters: [function (module) {
      loader = module.default;
    }, function (module) {
      __cjsMetaURL$1 = module.__cjsMetaURL;
    }, function (module) {
      __cjsMetaURL$2 = module.__cjsMetaURL;
    }, function (module) {
      __cjsMetaURL$3 = module.__cjsMetaURL;
    }, function (module) {
      __cjsMetaURL$4 = module.__cjsMetaURL;
    }, function (module) {
      __cjsMetaURL$5 = module.__cjsMetaURL;
    }],
    execute: function () {
      exports('default', void 0);

      var _cjsExports;

      var __cjsMetaURL = exports('__cjsMetaURL', module.meta.url);

      loader.define(__cjsMetaURL, function (exports$1, require, module, __filename, __dirname) {
        /*
         * Note
         * ====
         * the structure of this JavaScript version of poly2tri intentionally follows
         * as closely as possible the structure of the reference C++ version, to make it 
         * easier to keep the 2 versions in sync.
         */
        var PointError = require('./pointerror');

        var Point = require('./point');

        var Triangle = require('./triangle');

        var sweep = require('./sweep');

        var AdvancingFront = require('./advancingfront');

        var Node = AdvancingFront.Node; // ------------------------------------------------------------------------utils

        /**
         * Initial triangle factor, seed triangle will extend 30% of
         * PointSet width to both left and right.
         * @private
         * @const
         */

        var kAlpha = 0.3; // -------------------------------------------------------------------------Edge

        /**
         * Represents a simple polygon's edge
         * @constructor
         * @struct
         * @private
         * @param {Point} p1
         * @param {Point} p2
         * @throw {PointError} if p1 is same as p2
         */

        var Edge = function Edge(p1, p2) {
          this.p = p1;
          this.q = p2;

          if (p1.y > p2.y) {
            this.q = p1;
            this.p = p2;
          } else if (p1.y === p2.y) {
            if (p1.x > p2.x) {
              this.q = p1;
              this.p = p2;
            } else if (p1.x === p2.x) {
              throw new PointError('poly2tri Invalid Edge constructor: repeated points!', [p1]);
            }
          }

          if (!this.q._p2t_edge_list) {
            this.q._p2t_edge_list = [];
          }

          this.q._p2t_edge_list.push(this);
        }; // ------------------------------------------------------------------------Basin

        /**
         * @constructor
         * @struct
         * @private
         */


        var Basin = function Basin() {
          /** @type {Node} */
          this.left_node = null;
          /** @type {Node} */

          this.bottom_node = null;
          /** @type {Node} */

          this.right_node = null;
          /** @type {number} */

          this.width = 0.0;
          /** @type {boolean} */

          this.left_highest = false;
        };

        Basin.prototype.clear = function () {
          this.left_node = null;
          this.bottom_node = null;
          this.right_node = null;
          this.width = 0.0;
          this.left_highest = false;
        }; // --------------------------------------------------------------------EdgeEvent

        /**
         * @constructor
         * @struct
         * @private
         */


        var EdgeEvent = function EdgeEvent() {
          /** @type {Edge} */
          this.constrained_edge = null;
          /** @type {boolean} */

          this.right = false;
        }; // ----------------------------------------------------SweepContext (public API)

        /**
         * SweepContext constructor option
         * @typedef {Object} SweepContextOptions
         * @property {boolean=} cloneArrays - if <code>true</code>, do a shallow copy of the Array parameters
         *                  (contour, holes). Points inside arrays are never copied.
         *                  Default is <code>false</code> : keep a reference to the array arguments,
         *                  who will be modified in place.
         */

        /**
         * Constructor for the triangulation context.
         * It accepts a simple polyline (with non repeating points), 
         * which defines the constrained edges.
         *
         * @example
         *          var contour = [
         *              new poly2tri.Point(100, 100),
         *              new poly2tri.Point(100, 300),
         *              new poly2tri.Point(300, 300),
         *              new poly2tri.Point(300, 100)
         *          ];
         *          var swctx = new poly2tri.SweepContext(contour, {cloneArrays: true});
         * @example
         *          var contour = [{x:100, y:100}, {x:100, y:300}, {x:300, y:300}, {x:300, y:100}];
         *          var swctx = new poly2tri.SweepContext(contour, {cloneArrays: true});
         * @constructor
         * @public
         * @struct
         * @param {Array.<XY>} contour - array of point objects. The points can be either {@linkcode Point} instances,
         *          or any "Point like" custom class with <code>{x, y}</code> attributes.
         * @param {SweepContextOptions=} options - constructor options
         */


        var SweepContext = function SweepContext(contour, options) {
          options = options || {};
          this.triangles_ = [];
          this.map_ = [];
          this.points_ = options.cloneArrays ? contour.slice(0) : contour;
          this.edge_list = []; // Bounding box of all points. Computed at the start of the triangulation, 
          // it is stored in case it is needed by the caller.

          this.pmin_ = this.pmax_ = null;
          /**
           * Advancing front
           * @private
           * @type {AdvancingFront}
           */

          this.front_ = null;
          /**
           * head point used with advancing front
           * @private
           * @type {Point}
           */

          this.head_ = null;
          /**
           * tail point used with advancing front
           * @private
           * @type {Point}
           */

          this.tail_ = null;
          /**
           * @private
           * @type {Node}
           */

          this.af_head_ = null;
          /**
           * @private
           * @type {Node}
           */

          this.af_middle_ = null;
          /**
           * @private
           * @type {Node}
           */

          this.af_tail_ = null;
          this.basin = new Basin();
          this.edge_event = new EdgeEvent();
          this.initEdges(this.points_);
        };
        /**
         * Add a hole to the constraints
         * @example
         *      var swctx = new poly2tri.SweepContext(contour);
         *      var hole = [
         *          new poly2tri.Point(200, 200),
         *          new poly2tri.Point(200, 250),
         *          new poly2tri.Point(250, 250)
         *      ];
         *      swctx.addHole(hole);
         * @example
         *      var swctx = new poly2tri.SweepContext(contour);
         *      swctx.addHole([{x:200, y:200}, {x:200, y:250}, {x:250, y:250}]);
         * @public
         * @param {Array.<XY>} polyline - array of "Point like" objects with {x,y}
         */


        SweepContext.prototype.addHole = function (polyline) {
          this.initEdges(polyline);
          var i,
              len = polyline.length;

          for (i = 0; i < len; i++) {
            this.points_.push(polyline[i]);
          }

          return this; // for chaining
        };
        /**
         * For backward compatibility
         * @function
         * @deprecated use {@linkcode SweepContext#addHole} instead
         */


        SweepContext.prototype.AddHole = SweepContext.prototype.addHole;
        /**
         * Add several holes to the constraints
         * @example
         *      var swctx = new poly2tri.SweepContext(contour);
         *      var holes = [
         *          [ new poly2tri.Point(200, 200), new poly2tri.Point(200, 250), new poly2tri.Point(250, 250) ],
         *          [ new poly2tri.Point(300, 300), new poly2tri.Point(300, 350), new poly2tri.Point(350, 350) ]
         *      ];
         *      swctx.addHoles(holes);
         * @example
         *      var swctx = new poly2tri.SweepContext(contour);
         *      var holes = [
         *          [{x:200, y:200}, {x:200, y:250}, {x:250, y:250}],
         *          [{x:300, y:300}, {x:300, y:350}, {x:350, y:350}]
         *      ];
         *      swctx.addHoles(holes);
         * @public
         * @param {Array.<Array.<XY>>} holes - array of array of "Point like" objects with {x,y}
         */
        // Method added in the JavaScript version (was not present in the c++ version)

        SweepContext.prototype.addHoles = function (holes) {
          var i,
              len = holes.length;

          for (i = 0; i < len; i++) {
            this.initEdges(holes[i]);
          }

          this.points_ = this.points_.concat.apply(this.points_, holes);
          return this; // for chaining
        };
        /**
         * Add a Steiner point to the constraints
         * @example
         *      var swctx = new poly2tri.SweepContext(contour);
         *      var point = new poly2tri.Point(150, 150);
         *      swctx.addPoint(point);
         * @example
         *      var swctx = new poly2tri.SweepContext(contour);
         *      swctx.addPoint({x:150, y:150});
         * @public
         * @param {XY} point - any "Point like" object with {x,y}
         */


        SweepContext.prototype.addPoint = function (point) {
          this.points_.push(point);
          return this; // for chaining
        };
        /**
         * For backward compatibility
         * @function
         * @deprecated use {@linkcode SweepContext#addPoint} instead
         */


        SweepContext.prototype.AddPoint = SweepContext.prototype.addPoint;
        /**
         * Add several Steiner points to the constraints
         * @example
         *      var swctx = new poly2tri.SweepContext(contour);
         *      var points = [
         *          new poly2tri.Point(150, 150),
         *          new poly2tri.Point(200, 250),
         *          new poly2tri.Point(250, 250)
         *      ];
         *      swctx.addPoints(points);
         * @example
         *      var swctx = new poly2tri.SweepContext(contour);
         *      swctx.addPoints([{x:150, y:150}, {x:200, y:250}, {x:250, y:250}]);
         * @public
         * @param {Array.<XY>} points - array of "Point like" object with {x,y}
         */
        // Method added in the JavaScript version (was not present in the c++ version)

        SweepContext.prototype.addPoints = function (points) {
          this.points_ = this.points_.concat(points);
          return this; // for chaining
        };
        /**
         * Triangulate the polygon with holes and Steiner points.
         * Do this AFTER you've added the polyline, holes, and Steiner points
         * @example
         *      var swctx = new poly2tri.SweepContext(contour);
         *      swctx.triangulate();
         *      var triangles = swctx.getTriangles();
         * @public
         */
        // Shortcut method for sweep.triangulate(SweepContext).
        // Method added in the JavaScript version (was not present in the c++ version)


        SweepContext.prototype.triangulate = function () {
          sweep.triangulate(this);
          return this; // for chaining
        };
        /**
         * Get the bounding box of the provided constraints (contour, holes and 
         * Steinter points). Warning : these values are not available if the triangulation 
         * has not been done yet.
         * @public
         * @returns {{min:Point,max:Point}} object with 'min' and 'max' Point
         */
        // Method added in the JavaScript version (was not present in the c++ version)


        SweepContext.prototype.getBoundingBox = function () {
          return {
            min: this.pmin_,
            max: this.pmax_
          };
        };
        /**
         * Get result of triangulation.
         * The output triangles have vertices which are references
         * to the initial input points (not copies): any custom fields in the
         * initial points can be retrieved in the output triangles.
         * @example
         *      var swctx = new poly2tri.SweepContext(contour);
         *      swctx.triangulate();
         *      var triangles = swctx.getTriangles();
         * @example
         *      var contour = [{x:100, y:100, id:1}, {x:100, y:300, id:2}, {x:300, y:300, id:3}];
         *      var swctx = new poly2tri.SweepContext(contour);
         *      swctx.triangulate();
         *      var triangles = swctx.getTriangles();
         *      typeof triangles[0].getPoint(0).id
         *      // → "number"
         * @public
         * @returns {array<Triangle>}   array of triangles
         */


        SweepContext.prototype.getTriangles = function () {
          return this.triangles_;
        };
        /**
         * For backward compatibility
         * @function
         * @deprecated use {@linkcode SweepContext#getTriangles} instead
         */


        SweepContext.prototype.GetTriangles = SweepContext.prototype.getTriangles; // ---------------------------------------------------SweepContext (private API)

        /** @private */

        SweepContext.prototype.front = function () {
          return this.front_;
        };
        /** @private */


        SweepContext.prototype.pointCount = function () {
          return this.points_.length;
        };
        /** @private */


        SweepContext.prototype.head = function () {
          return this.head_;
        };
        /** @private */


        SweepContext.prototype.setHead = function (p1) {
          this.head_ = p1;
        };
        /** @private */


        SweepContext.prototype.tail = function () {
          return this.tail_;
        };
        /** @private */


        SweepContext.prototype.setTail = function (p1) {
          this.tail_ = p1;
        };
        /** @private */


        SweepContext.prototype.getMap = function () {
          return this.map_;
        };
        /** @private */


        SweepContext.prototype.initTriangulation = function () {
          var xmax = this.points_[0].x;
          var xmin = this.points_[0].x;
          var ymax = this.points_[0].y;
          var ymin = this.points_[0].y; // Calculate bounds

          var i,
              len = this.points_.length;

          for (i = 1; i < len; i++) {
            var p = this.points_[i];
            /* jshint expr:true */

            p.x > xmax && (xmax = p.x);
            p.x < xmin && (xmin = p.x);
            p.y > ymax && (ymax = p.y);
            p.y < ymin && (ymin = p.y);
          }

          this.pmin_ = new Point(xmin, ymin);
          this.pmax_ = new Point(xmax, ymax);
          var dx = kAlpha * (xmax - xmin);
          var dy = kAlpha * (ymax - ymin);
          this.head_ = new Point(xmax + dx, ymin - dy);
          this.tail_ = new Point(xmin - dx, ymin - dy); // Sort points along y-axis

          this.points_.sort(Point.compare);
        };
        /** @private */


        SweepContext.prototype.initEdges = function (polyline) {
          var i,
              len = polyline.length;

          for (i = 0; i < len; ++i) {
            this.edge_list.push(new Edge(polyline[i], polyline[(i + 1) % len]));
          }
        };
        /** @private */


        SweepContext.prototype.getPoint = function (index) {
          return this.points_[index];
        };
        /** @private */


        SweepContext.prototype.addToMap = function (triangle) {
          this.map_.push(triangle);
        };
        /** @private */


        SweepContext.prototype.locateNode = function (point) {
          return this.front_.locateNode(point.x);
        };
        /** @private */


        SweepContext.prototype.createAdvancingFront = function () {
          var head;
          var middle;
          var tail; // Initial triangle

          var triangle = new Triangle(this.points_[0], this.tail_, this.head_);
          this.map_.push(triangle);
          head = new Node(triangle.getPoint(1), triangle);
          middle = new Node(triangle.getPoint(0), triangle);
          tail = new Node(triangle.getPoint(2));
          this.front_ = new AdvancingFront(head, tail);
          head.next = middle;
          middle.next = tail;
          middle.prev = head;
          tail.prev = middle;
        };
        /** @private */


        SweepContext.prototype.removeNode = function (node) {// do nothing

          /* jshint unused:false */
        };
        /** @private */


        SweepContext.prototype.mapTriangleToNodes = function (t) {
          for (var i = 0; i < 3; ++i) {
            if (!t.getNeighbor(i)) {
              var n = this.front_.locatePoint(t.pointCW(t.getPoint(i)));

              if (n) {
                n.triangle = t;
              }
            }
          }
        };
        /** @private */


        SweepContext.prototype.removeFromMap = function (triangle) {
          var i,
              map = this.map_,
              len = map.length;

          for (i = 0; i < len; i++) {
            if (map[i] === triangle) {
              map.splice(i, 1);
              break;
            }
          }
        };
        /**
         * Do a depth first traversal to collect triangles
         * @private
         * @param {Triangle} triangle start
         */


        SweepContext.prototype.meshClean = function (triangle) {
          // New implementation avoids recursive calls and use a loop instead.
          // Cf. issues # 57, 65 and 69.
          var triangles = [triangle],
              t,
              i;
          /* jshint boss:true */

          while (t = triangles.pop()) {
            if (!t.isInterior()) {
              t.setInterior(true);
              this.triangles_.push(t);

              for (i = 0; i < 3; i++) {
                if (!t.constrained_edge[i]) {
                  triangles.push(t.getNeighbor(i));
                }
              }
            }
          }
        }; // ----------------------------------------------------------------------Exports


        module.exports = SweepContext; // #endregion ORIGINAL CODE

        _cjsExports = exports('default', module.exports);
      }, function () {
        return {
          './pointerror': __cjsMetaURL$1,
          './point': __cjsMetaURL$2,
          './triangle': __cjsMetaURL$3,
          './sweep': __cjsMetaURL$4,
          './advancingfront': __cjsMetaURL$5
        };
      });
    }
  };
});

System.register("chunks:///_virtual/triangle.js", ['./cjs-loader.mjs', './xy.js'], function (exports, module) {
  var loader, __cjsMetaURL$1;

  return {
    setters: [function (module) {
      loader = module.default;
    }, function (module) {
      __cjsMetaURL$1 = module.__cjsMetaURL;
    }],
    execute: function () {
      exports('default', void 0);

      var _cjsExports;

      var __cjsMetaURL = exports('__cjsMetaURL', module.meta.url);

      loader.define(__cjsMetaURL, function (exports$1, require, module, __filename, __dirname) {
        /*
         * Note
         * ====
         * the structure of this JavaScript version of poly2tri intentionally follows
         * as closely as possible the structure of the reference C++ version, to make it 
         * easier to keep the 2 versions in sync.
         */
        var xy = require("./xy"); // ---------------------------------------------------------------------Triangle

        /**
         * Triangle class.<br>
         * Triangle-based data structures are known to have better performance than
         * quad-edge structures.
         * See: J. Shewchuk, "Triangle: Engineering a 2D Quality Mesh Generator and
         * Delaunay Triangulator", "Triangulations in CGAL"
         *
         * @constructor
         * @struct
         * @param {!XY} pa  point object with {x,y}
         * @param {!XY} pb  point object with {x,y}
         * @param {!XY} pc  point object with {x,y}
         */


        var Triangle = function Triangle(a, b, c) {
          /**
           * Triangle points
           * @private
           * @type {Array.<XY>}
           */
          this.points_ = [a, b, c];
          /**
           * Neighbor list
           * @private
           * @type {Array.<Triangle>}
           */

          this.neighbors_ = [null, null, null];
          /**
           * Has this triangle been marked as an interior triangle?
           * @private
           * @type {boolean}
           */

          this.interior_ = false;
          /**
           * Flags to determine if an edge is a Constrained edge
           * @private
           * @type {Array.<boolean>}
           */

          this.constrained_edge = [false, false, false];
          /**
           * Flags to determine if an edge is a Delauney edge
           * @private
           * @type {Array.<boolean>}
           */

          this.delaunay_edge = [false, false, false];
        };

        var p2s = xy.toString;
        /**
         * For pretty printing ex. <code>"[(5;42)(10;20)(21;30)]"</code>.
         * @public
         * @return {string}
         */

        Triangle.prototype.toString = function () {
          return "[" + p2s(this.points_[0]) + p2s(this.points_[1]) + p2s(this.points_[2]) + "]";
        };
        /**
         * Get one vertice of the triangle.
         * The output triangles of a triangulation have vertices which are references
         * to the initial input points (not copies): any custom fields in the
         * initial points can be retrieved in the output triangles.
         * @example
         *      var contour = [{x:100, y:100, id:1}, {x:100, y:300, id:2}, {x:300, y:300, id:3}];
         *      var swctx = new poly2tri.SweepContext(contour);
         *      swctx.triangulate();
         *      var triangles = swctx.getTriangles();
         *      typeof triangles[0].getPoint(0).id
         *      // → "number"
         * @param {number} index - vertice index: 0, 1 or 2
         * @public
         * @returns {XY}
         */


        Triangle.prototype.getPoint = function (index) {
          return this.points_[index];
        };
        /**
         * For backward compatibility
         * @function
         * @deprecated use {@linkcode Triangle#getPoint} instead
         */


        Triangle.prototype.GetPoint = Triangle.prototype.getPoint;
        /**
         * Get all 3 vertices of the triangle as an array
         * @public
         * @return {Array.<XY>}
         */
        // Method added in the JavaScript version (was not present in the c++ version)

        Triangle.prototype.getPoints = function () {
          return this.points_;
        };
        /**
         * @private
         * @param {number} index
         * @returns {?Triangle}
         */


        Triangle.prototype.getNeighbor = function (index) {
          return this.neighbors_[index];
        };
        /**
         * Test if this Triangle contains the Point object given as parameter as one of its vertices.
         * Only point references are compared, not values.
         * @public
         * @param {XY} point - point object with {x,y}
         * @return {boolean} <code>True</code> if the Point object is of the Triangle's vertices,
         *         <code>false</code> otherwise.
         */


        Triangle.prototype.containsPoint = function (point) {
          var points = this.points_; // Here we are comparing point references, not values

          return point === points[0] || point === points[1] || point === points[2];
        };
        /**
         * Test if this Triangle contains the Edge object given as parameter as its
         * bounding edges. Only point references are compared, not values.
         * @private
         * @param {Edge} edge
         * @return {boolean} <code>True</code> if the Edge object is of the Triangle's bounding
         *         edges, <code>false</code> otherwise.
         */


        Triangle.prototype.containsEdge = function (edge) {
          return this.containsPoint(edge.p) && this.containsPoint(edge.q);
        };
        /**
         * Test if this Triangle contains the two Point objects given as parameters among its vertices.
         * Only point references are compared, not values.
         * @param {XY} p1 - point object with {x,y}
         * @param {XY} p2 - point object with {x,y}
         * @return {boolean}
         */


        Triangle.prototype.containsPoints = function (p1, p2) {
          return this.containsPoint(p1) && this.containsPoint(p2);
        };
        /**
         * Has this triangle been marked as an interior triangle?
         * @returns {boolean}
         */


        Triangle.prototype.isInterior = function () {
          return this.interior_;
        };
        /**
         * Mark this triangle as an interior triangle
         * @private
         * @param {boolean} interior
         * @returns {Triangle} this
         */


        Triangle.prototype.setInterior = function (interior) {
          this.interior_ = interior;
          return this;
        };
        /**
         * Update neighbor pointers.
         * @private
         * @param {XY} p1 - point object with {x,y}
         * @param {XY} p2 - point object with {x,y}
         * @param {Triangle} t Triangle object.
         * @throws {Error} if can't find objects
         */


        Triangle.prototype.markNeighborPointers = function (p1, p2, t) {
          var points = this.points_; // Here we are comparing point references, not values

          if (p1 === points[2] && p2 === points[1] || p1 === points[1] && p2 === points[2]) {
            this.neighbors_[0] = t;
          } else if (p1 === points[0] && p2 === points[2] || p1 === points[2] && p2 === points[0]) {
            this.neighbors_[1] = t;
          } else if (p1 === points[0] && p2 === points[1] || p1 === points[1] && p2 === points[0]) {
            this.neighbors_[2] = t;
          } else {
            throw new Error('poly2tri Invalid Triangle.markNeighborPointers() call');
          }
        };
        /**
         * Exhaustive search to update neighbor pointers
         * @private
         * @param {!Triangle} t
         */


        Triangle.prototype.markNeighbor = function (t) {
          var points = this.points_;

          if (t.containsPoints(points[1], points[2])) {
            this.neighbors_[0] = t;
            t.markNeighborPointers(points[1], points[2], this);
          } else if (t.containsPoints(points[0], points[2])) {
            this.neighbors_[1] = t;
            t.markNeighborPointers(points[0], points[2], this);
          } else if (t.containsPoints(points[0], points[1])) {
            this.neighbors_[2] = t;
            t.markNeighborPointers(points[0], points[1], this);
          }
        };

        Triangle.prototype.clearNeighbors = function () {
          this.neighbors_[0] = null;
          this.neighbors_[1] = null;
          this.neighbors_[2] = null;
        };

        Triangle.prototype.clearDelaunayEdges = function () {
          this.delaunay_edge[0] = false;
          this.delaunay_edge[1] = false;
          this.delaunay_edge[2] = false;
        };
        /**
         * Returns the point clockwise to the given point.
         * @private
         * @param {XY} p - point object with {x,y}
         */


        Triangle.prototype.pointCW = function (p) {
          var points = this.points_; // Here we are comparing point references, not values

          if (p === points[0]) {
            return points[2];
          } else if (p === points[1]) {
            return points[0];
          } else if (p === points[2]) {
            return points[1];
          } else {
            return null;
          }
        };
        /**
         * Returns the point counter-clockwise to the given point.
         * @private
         * @param {XY} p - point object with {x,y}
         */


        Triangle.prototype.pointCCW = function (p) {
          var points = this.points_; // Here we are comparing point references, not values

          if (p === points[0]) {
            return points[1];
          } else if (p === points[1]) {
            return points[2];
          } else if (p === points[2]) {
            return points[0];
          } else {
            return null;
          }
        };
        /**
         * Returns the neighbor clockwise to given point.
         * @private
         * @param {XY} p - point object with {x,y}
         */


        Triangle.prototype.neighborCW = function (p) {
          // Here we are comparing point references, not values
          if (p === this.points_[0]) {
            return this.neighbors_[1];
          } else if (p === this.points_[1]) {
            return this.neighbors_[2];
          } else {
            return this.neighbors_[0];
          }
        };
        /**
         * Returns the neighbor counter-clockwise to given point.
         * @private
         * @param {XY} p - point object with {x,y}
         */


        Triangle.prototype.neighborCCW = function (p) {
          // Here we are comparing point references, not values
          if (p === this.points_[0]) {
            return this.neighbors_[2];
          } else if (p === this.points_[1]) {
            return this.neighbors_[0];
          } else {
            return this.neighbors_[1];
          }
        };

        Triangle.prototype.getConstrainedEdgeCW = function (p) {
          // Here we are comparing point references, not values
          if (p === this.points_[0]) {
            return this.constrained_edge[1];
          } else if (p === this.points_[1]) {
            return this.constrained_edge[2];
          } else {
            return this.constrained_edge[0];
          }
        };

        Triangle.prototype.getConstrainedEdgeCCW = function (p) {
          // Here we are comparing point references, not values
          if (p === this.points_[0]) {
            return this.constrained_edge[2];
          } else if (p === this.points_[1]) {
            return this.constrained_edge[0];
          } else {
            return this.constrained_edge[1];
          }
        }; // Additional check from Java version (see issue #88)


        Triangle.prototype.getConstrainedEdgeAcross = function (p) {
          // Here we are comparing point references, not values
          if (p === this.points_[0]) {
            return this.constrained_edge[0];
          } else if (p === this.points_[1]) {
            return this.constrained_edge[1];
          } else {
            return this.constrained_edge[2];
          }
        };

        Triangle.prototype.setConstrainedEdgeCW = function (p, ce) {
          // Here we are comparing point references, not values
          if (p === this.points_[0]) {
            this.constrained_edge[1] = ce;
          } else if (p === this.points_[1]) {
            this.constrained_edge[2] = ce;
          } else {
            this.constrained_edge[0] = ce;
          }
        };

        Triangle.prototype.setConstrainedEdgeCCW = function (p, ce) {
          // Here we are comparing point references, not values
          if (p === this.points_[0]) {
            this.constrained_edge[2] = ce;
          } else if (p === this.points_[1]) {
            this.constrained_edge[0] = ce;
          } else {
            this.constrained_edge[1] = ce;
          }
        };

        Triangle.prototype.getDelaunayEdgeCW = function (p) {
          // Here we are comparing point references, not values
          if (p === this.points_[0]) {
            return this.delaunay_edge[1];
          } else if (p === this.points_[1]) {
            return this.delaunay_edge[2];
          } else {
            return this.delaunay_edge[0];
          }
        };

        Triangle.prototype.getDelaunayEdgeCCW = function (p) {
          // Here we are comparing point references, not values
          if (p === this.points_[0]) {
            return this.delaunay_edge[2];
          } else if (p === this.points_[1]) {
            return this.delaunay_edge[0];
          } else {
            return this.delaunay_edge[1];
          }
        };

        Triangle.prototype.setDelaunayEdgeCW = function (p, e) {
          // Here we are comparing point references, not values
          if (p === this.points_[0]) {
            this.delaunay_edge[1] = e;
          } else if (p === this.points_[1]) {
            this.delaunay_edge[2] = e;
          } else {
            this.delaunay_edge[0] = e;
          }
        };

        Triangle.prototype.setDelaunayEdgeCCW = function (p, e) {
          // Here we are comparing point references, not values
          if (p === this.points_[0]) {
            this.delaunay_edge[2] = e;
          } else if (p === this.points_[1]) {
            this.delaunay_edge[0] = e;
          } else {
            this.delaunay_edge[1] = e;
          }
        };
        /**
         * The neighbor across to given point.
         * @private
         * @param {XY} p - point object with {x,y}
         * @returns {Triangle}
         */


        Triangle.prototype.neighborAcross = function (p) {
          // Here we are comparing point references, not values
          if (p === this.points_[0]) {
            return this.neighbors_[0];
          } else if (p === this.points_[1]) {
            return this.neighbors_[1];
          } else {
            return this.neighbors_[2];
          }
        };
        /**
         * @private
         * @param {!Triangle} t Triangle object.
         * @param {XY} p - point object with {x,y}
         */


        Triangle.prototype.oppositePoint = function (t, p) {
          var cw = t.pointCW(p);
          return this.pointCW(cw);
        };
        /**
         * Legalize triangle by rotating clockwise around oPoint
         * @private
         * @param {XY} opoint - point object with {x,y}
         * @param {XY} npoint - point object with {x,y}
         * @throws {Error} if oPoint can not be found
         */


        Triangle.prototype.legalize = function (opoint, npoint) {
          var points = this.points_; // Here we are comparing point references, not values

          if (opoint === points[0]) {
            points[1] = points[0];
            points[0] = points[2];
            points[2] = npoint;
          } else if (opoint === points[1]) {
            points[2] = points[1];
            points[1] = points[0];
            points[0] = npoint;
          } else if (opoint === points[2]) {
            points[0] = points[2];
            points[2] = points[1];
            points[1] = npoint;
          } else {
            throw new Error('poly2tri Invalid Triangle.legalize() call');
          }
        };
        /**
         * Returns the index of a point in the triangle. 
         * The point *must* be a reference to one of the triangle's vertices.
         * @private
         * @param {XY} p - point object with {x,y}
         * @returns {number} index 0, 1 or 2
         * @throws {Error} if p can not be found
         */


        Triangle.prototype.index = function (p) {
          var points = this.points_; // Here we are comparing point references, not values

          if (p === points[0]) {
            return 0;
          } else if (p === points[1]) {
            return 1;
          } else if (p === points[2]) {
            return 2;
          } else {
            throw new Error('poly2tri Invalid Triangle.index() call');
          }
        };
        /**
         * @private
         * @param {XY} p1 - point object with {x,y}
         * @param {XY} p2 - point object with {x,y}
         * @return {number} index 0, 1 or 2, or -1 if errror
         */


        Triangle.prototype.edgeIndex = function (p1, p2) {
          var points = this.points_; // Here we are comparing point references, not values

          if (p1 === points[0]) {
            if (p2 === points[1]) {
              return 2;
            } else if (p2 === points[2]) {
              return 1;
            }
          } else if (p1 === points[1]) {
            if (p2 === points[2]) {
              return 0;
            } else if (p2 === points[0]) {
              return 2;
            }
          } else if (p1 === points[2]) {
            if (p2 === points[0]) {
              return 1;
            } else if (p2 === points[1]) {
              return 0;
            }
          }

          return -1;
        };
        /**
         * Mark an edge of this triangle as constrained.
         * @private
         * @param {number} index - edge index
         */


        Triangle.prototype.markConstrainedEdgeByIndex = function (index) {
          this.constrained_edge[index] = true;
        };
        /**
         * Mark an edge of this triangle as constrained.
         * @private
         * @param {Edge} edge instance
         */


        Triangle.prototype.markConstrainedEdgeByEdge = function (edge) {
          this.markConstrainedEdgeByPoints(edge.p, edge.q);
        };
        /**
         * Mark an edge of this triangle as constrained.
         * This method takes two Point instances defining the edge of the triangle.
         * @private
         * @param {XY} p - point object with {x,y}
         * @param {XY} q - point object with {x,y}
         */


        Triangle.prototype.markConstrainedEdgeByPoints = function (p, q) {
          var points = this.points_; // Here we are comparing point references, not values        

          if (q === points[0] && p === points[1] || q === points[1] && p === points[0]) {
            this.constrained_edge[2] = true;
          } else if (q === points[0] && p === points[2] || q === points[2] && p === points[0]) {
            this.constrained_edge[1] = true;
          } else if (q === points[1] && p === points[2] || q === points[2] && p === points[1]) {
            this.constrained_edge[0] = true;
          }
        }; // ---------------------------------------------------------Exports (public API)


        module.exports = Triangle; // #endregion ORIGINAL CODE

        _cjsExports = exports('default', module.exports);
      }, function () {
        return {
          './xy': __cjsMetaURL$1
        };
      });
    }
  };
});

System.register("chunks:///_virtual/updateValueLabel.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc'], function (exports) {
  var _inheritsLoose, cclegacy, _decorator, Label, Component;

  return {
    setters: [function (module) {
      _inheritsLoose = module.inheritsLoose;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
      Label = module.Label;
      Component = module.Component;
    }],
    execute: function () {
      var _dec, _dec2, _class;

      cclegacy._RF.push({}, "5391cANIWdJn6Av5jRP9uv2", "updateValueLabel", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property,
          requireComponent = _decorator.requireComponent;
      var updateValueLabel = exports('updateValueLabel', (_dec = ccclass("updateValueLabel"), _dec2 = requireComponent(Label), _dec(_class = _dec2(_class = /*#__PURE__*/function (_Component) {
        _inheritsLoose(updateValueLabel, _Component);

        function updateValueLabel() {
          var _this;

          for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          _this = _Component.call.apply(_Component, [this].concat(args)) || this;
          _this.isPlaying = false;
          _this.startVal = 0;
          _this.endVal = 0;
          _this.diffVal = 0;
          _this.currTime = 0;
          _this.changingTime = 0;
          _this.label = null;
          return _this;
        }

        var _proto = updateValueLabel.prototype;

        _proto.start = function start() {// Your initialization goes here.
        };

        _proto.playUpdateValue = function playUpdateValue(startVal, endVal, changingTime) {
          this.startVal = startVal;
          this.endVal = endVal;
          this.diffVal = this.endVal - this.startVal;
          this.currTime = 0;
          this.changingTime = changingTime;
          this.label = this.node.getComponent(Label);
          this.label.string = startVal.toString();
          this.isPlaying = true;
        };

        _proto.update = function update(dt) {
          if (!this.isPlaying) {
            return;
          }

          if (this.currTime < this.changingTime) {
            this.currTime += dt;
            var currVal = this.startVal + parseInt((this.currTime / this.changingTime * this.diffVal).toString());

            if (currVal < this.startVal) {
              currVal = this.startVal;
            } else if (currVal > this.endVal) {
              currVal = this.endVal;
            }

            this.label.string = "" + currVal;
            return;
          }

          this.label.string = "" + this.endVal;
          this.isPlaying = false;
        } // update (deltaTime) {
        //     // Your update function goes here.
        // }
        ;

        return updateValueLabel;
      }(Component)) || _class) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/utils.js", ['./cjs-loader.mjs'], function (exports, module) {
  var loader;
  return {
    setters: [function (module) {
      loader = module.default;
    }],
    execute: function () {
      exports('default', void 0);

      var _cjsExports;

      var __cjsMetaURL = exports('__cjsMetaURL', module.meta.url);

      loader.define(__cjsMetaURL, function (exports$1, require, module, __filename, __dirname) {
        /**
         * Precision to detect repeated or collinear points
         * @private
         * @const {number}
         * @default
         */
        var EPSILON = 1e-12;
        exports$1.EPSILON = EPSILON;
        /**
         * @private
         * @enum {number}
         * @readonly
         */

        var Orientation = {
          "CW": 1,
          "CCW": -1,
          "COLLINEAR": 0
        };
        exports$1.Orientation = Orientation;
        /**
         * Formula to calculate signed area<br>
         * Positive if CCW<br>
         * Negative if CW<br>
         * 0 if collinear<br>
         * <pre>
         * A[P1,P2,P3]  =  (x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y1 - y3*x1)
         *              =  (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
         * </pre>
         *
         * @private
         * @param {!XY} pa  point object with {x,y}
         * @param {!XY} pb  point object with {x,y}
         * @param {!XY} pc  point object with {x,y}
         * @return {Orientation}
         */

        function orient2d(pa, pb, pc) {
          var detleft = (pa.x - pc.x) * (pb.y - pc.y);
          var detright = (pa.y - pc.y) * (pb.x - pc.x);
          var val = detleft - detright;

          if (val > -EPSILON && val < EPSILON) {
            return Orientation.COLLINEAR;
          } else if (val > 0) {
            return Orientation.CCW;
          } else {
            return Orientation.CW;
          }
        }

        exports$1.orient2d = orient2d;
        /**
         *
         * @private
         * @param {!XY} pa  point object with {x,y}
         * @param {!XY} pb  point object with {x,y}
         * @param {!XY} pc  point object with {x,y}
         * @param {!XY} pd  point object with {x,y}
         * @return {boolean}
         */

        function inScanArea(pa, pb, pc, pd) {
          var oadb = (pa.x - pb.x) * (pd.y - pb.y) - (pd.x - pb.x) * (pa.y - pb.y);

          if (oadb >= -EPSILON) {
            return false;
          }

          var oadc = (pa.x - pc.x) * (pd.y - pc.y) - (pd.x - pc.x) * (pa.y - pc.y);

          if (oadc <= EPSILON) {
            return false;
          }

          return true;
        }

        exports$1.inScanArea = inScanArea;
        /**
         * Check if the angle between (pa,pb) and (pa,pc) is obtuse i.e. (angle > π/2 || angle < -π/2)
         *
         * @private
         * @param {!XY} pa  point object with {x,y}
         * @param {!XY} pb  point object with {x,y}
         * @param {!XY} pc  point object with {x,y}
         * @return {boolean} true if angle is obtuse
         */

        function isAngleObtuse(pa, pb, pc) {
          var ax = pb.x - pa.x;
          var ay = pb.y - pa.y;
          var bx = pc.x - pa.x;
          var by = pc.y - pa.y;
          return ax * bx + ay * by < 0;
        }

        exports$1.isAngleObtuse = isAngleObtuse; // #endregion ORIGINAL CODE

        _cjsExports = exports('default', module.exports);
        module.exports.EPSILON;
        module.exports.Orientation;
        module.exports.orient2d;
        module.exports.inScanArea;
        module.exports.isAngleObtuse;
      }, {});
    }
  };
});

System.register("chunks:///_virtual/VibrateManager.ts", ['./rollupPluginModLoBabelHelpers.js', 'cc', './GlobalData.ts'], function (exports) {
  var _createClass, cclegacy, _decorator, GlobalData;

  return {
    setters: [function (module) {
      _createClass = module.createClass;
    }, function (module) {
      cclegacy = module.cclegacy;
      _decorator = module._decorator;
    }, function (module) {
      GlobalData = module.GlobalData;
    }],
    execute: function () {
      var _dec, _class, _class2;

      cclegacy._RF.push({}, "d04ffD52CRAMblUmWP9I1Mg", "VibrateManager", undefined);

      var ccclass = _decorator.ccclass,
          property = _decorator.property;
      var VibrateManager = exports('VibrateManager', (_dec = ccclass('VibrateManager'), _dec(_class = (_class2 = /*#__PURE__*/function () {
        function VibrateManager() {}

        var _proto = VibrateManager.prototype;
        /**
         * 触发震动，若设备不支持震动，该方法将无效。若某震动方式已经在进行中（当该方法调用时），则前一个震动方式停止
         * @param duration 单位ms
         */

        _proto.vibrateShort = function vibrateShort() {
          var isVibrateOpen = GlobalData.instance.getGlobalStorgeData(VibrateManager.GLOBAL_KEY_VIBRATE_ENABLE);

          if (isVibrateOpen) {
            {
              console.log("err: platform not support vibrate!");
            }
          }
        };

        _proto.vibrateLong = function vibrateLong() {
          var isVibrateOpen = GlobalData.instance.getGlobalStorgeData(VibrateManager.GLOBAL_KEY_VIBRATE_ENABLE);

          if (isVibrateOpen) {
            {
              console.log("err: platform not support vibrate!");
            }
          }
        };

        _createClass(VibrateManager, null, [{
          key: "instance",
          get: function get() {
            if (this._instance) {
              return this._instance;
            }

            this._instance = new VibrateManager();
            return this._instance;
          }
        }]);

        return VibrateManager;
      }(), _class2.GLOBAL_KEY_VIBRATE_ENABLE = "GLOBAL_KEY_VIBRATE_ENABLE", _class2._instance = void 0, _class2)) || _class));

      cclegacy._RF.pop();
    }
  };
});

System.register("chunks:///_virtual/xy.js", ['./cjs-loader.mjs'], function (exports, module) {
  var loader;
  return {
    setters: [function (module) {
      loader = module.default;
    }],
    execute: function () {
      exports('default', void 0);

      var _cjsExports;

      var __cjsMetaURL = exports('__cjsMetaURL', module.meta.url);

      loader.define(__cjsMetaURL, function (exports$1, require, module, __filename, __dirname) {
        /**
         * The following functions operate on "Point" or any "Point like" object with {x,y},
         * as defined by the {@link XY} type
         * ([duck typing]{@link http://en.wikipedia.org/wiki/Duck_typing}).
         * @module
         * @private
         */

        /**
         * poly2tri.js supports using custom point class instead of {@linkcode Point}.
         * Any "Point like" object with <code>{x, y}</code> attributes is supported
         * to initialize the SweepContext polylines and points
         * ([duck typing]{@link http://en.wikipedia.org/wiki/Duck_typing}).
         *
         * poly2tri.js might add extra fields to the point objects when computing the
         * triangulation : they are prefixed with <code>_p2t_</code> to avoid collisions
         * with fields in the custom class.
         *
         * @example
         *      var contour = [{x:100, y:100}, {x:100, y:300}, {x:300, y:300}, {x:300, y:100}];
         *      var swctx = new poly2tri.SweepContext(contour);
         *
         * @typedef {Object} XY
         * @property {number} x - x coordinate
         * @property {number} y - y coordinate
         */

        /**
         * Point pretty printing : prints x and y coordinates.
         * @example
         *      xy.toStringBase({x:5, y:42})
         *      // → "(5;42)"
         * @protected
         * @param {!XY} p - point object with {x,y}
         * @returns {string} <code>"(x;y)"</code>
         */
        function toStringBase(p) {
          return "(" + p.x + ";" + p.y + ")";
        }
        /**
         * Point pretty printing. Delegates to the point's custom "toString()" method if exists,
         * else simply prints x and y coordinates.
         * @example
         *      xy.toString({x:5, y:42})
         *      // → "(5;42)"
         * @example
         *      xy.toString({x:5,y:42,toString:function() {return this.x+":"+this.y;}})
         *      // → "5:42"
         * @param {!XY} p - point object with {x,y}
         * @returns {string} <code>"(x;y)"</code>
         */


        function toString(p) {
          // Try a custom toString first, and fallback to own implementation if none
          var s = p.toString();
          return s === '[object Object]' ? toStringBase(p) : s;
        }
        /**
         * Compare two points component-wise. Ordered by y axis first, then x axis.
         * @param {!XY} a - point object with {x,y}
         * @param {!XY} b - point object with {x,y}
         * @return {number} <code>&lt; 0</code> if <code>a &lt; b</code>,
         *         <code>&gt; 0</code> if <code>a &gt; b</code>, 
         *         <code>0</code> otherwise.
         */


        function compare(a, b) {
          if (a.y === b.y) {
            return a.x - b.x;
          } else {
            return a.y - b.y;
          }
        }
        /**
         * Test two Point objects for equality.
         * @param {!XY} a - point object with {x,y}
         * @param {!XY} b - point object with {x,y}
         * @return {boolean} <code>True</code> if <code>a == b</code>, <code>false</code> otherwise.
         */


        function equals(a, b) {
          return a.x === b.x && a.y === b.y;
        }

        module.exports = {
          toString: toString,
          toStringBase: toStringBase,
          compare: compare,
          equals: equals
        }; // #endregion ORIGINAL CODE

        _cjsExports = exports('default', module.exports);
        module.exports.toString;
        module.exports.toStringBase;
        module.exports.compare;
        module.exports.equals;
      }, {});
    }
  };
});

(function(r) {
  r('virtual:///prerequisite-imports/main', 'chunks:///_virtual/main'); 
})(function(mid, cid) {
    System.register(mid, [cid], function (_export, _context) {
    return {
        setters: [function(_m) {
            var _exportObj = {};

            for (var _key in _m) {
              if (_key !== "default" && _key !== "__esModule") _exportObj[_key] = _m[_key];
            }
      
            _export(_exportObj);
        }],
        execute: function () { }
    };
    });
});